Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

segmentation fault when accessing pointer element

I have been attempting to parse a string into separate tokens for a command line interface for a project of mine, I have created this function to do it:

char **string_parser(char *input) {
    char **output = (char **) malloc(sizeof(input));
    int word_num = 0;
    int word_index = 0;

    for(int i = 0; i < strlen(input); i++) {
        if(input[i] == ' ') {
            output[word_num][word_index] = '\0';
            word_index = 0;
            word_num++;
            continue;
        }

        if(input[i] == '\0') {
            output[word_num][word_index] = '\0';
            break;
        }

        output[word_num][word_index] = input[i];
        word_index++;
    }

    return output;
}

but it segmentation faults after 1 iteration,

I have been calling the function on:
char *input = "this is a parser test.";
any help is greatly appreciated.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

This memory allocation

char **output = (char **) malloc(sizeof(input));

is incorrect. It allocates memory only for one object of the type char *.

Moreover the allocated memory is uninitialized. So at least this statement (and similar statements)

output[word_num][word_index] = '\0';

invokes undefined behavior.

You need to allocate as many pointers as there are words in the source string. And for each word you also need to allocate a character array to store the extracted word.

And calling the function strlen in the for loop

for(int i = 0; i < strlen(input); i++) {

is redundant and inefficient.

Pay attention to that the function parameter should be declared with qualifier const because the source string is not changed within the function.

Here is a demonstration program that shows an approach to the function implementation. The function has drawbacks because it does not check that memory allocations were successfull. You will need to do that yourself. The last pointer in the allocated array of pointers is set to NULL to allow to determine the number of valid extracted words.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char ** string_parser( const char *input ) 
{
    char **output = NULL;
    size_t word_num = 0;

    for (const char *delim = " \t"; *input != '\0'; )
    {
        input += strspn( input, delim );

        if (*input)
        {
            size_t n = strcspn( input, delim );

            output = realloc( output, ( word_num + 1 ) * sizeof( char * ) );

            output[word_num] = malloc( n + 1 );

            memcpy( output[word_num], input, n );
            output[word_num][n] = '\0';
            ++word_num;

            input += n;
        }
    }

    output = realloc( output, ( word_num + 1 ) * sizeof( char * ) );

    output[word_num] = NULL;

    return output;
}

int main( void )
{
    const char *input = "this is a parser test.";

    char **output = string_parser( input );

    for (char **p = output; *p != NULL; ++p)
    {
        puts( *p );
    }

    for (char **p = output; *p != NULL; ++p)
    {
        free( *p );
    }
    free( output );
}

The program output is

this
is
a
parser
test.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading