user3344699
user3344699

Reputation: 39

Issue working with double pointers

I'm new to C and having trouble wrapping my head around double pointers and keep getting segmentation fault errors. I've debugged the program a bit and located where things go wrong, but can't for the life of me figure out why. I'll post my code first:

int main() { 
    printf("Enter string to be split: \n");
    a = readline();
    String *st = newString(a);
    String **split;
    int num;
    num = string_split(st, ',', split);
    for (i=0; i<num; i++) { print_string(*(split+i)); }
}

readline() produces a pointer to an array of chars (entered by the user) and appends '\0' to it. newString and print_string definitely work. Here's the struct for string:

typedef struct {
    char *chars;
    int length;
    int maxSize;
} String;

And here is the code for string_split which is causing me all this trouble.

int string_split(String *s, char delim, String **arrayOfStructs) {
    char *c = getCharacters(s);
    int len = length(s);
    int begin = 0;
    int end;

    int arraycount = 0;
    String **temp = (String**)malloc(sizeof(String*));

    for (end=0; end<len+1; end++) {
        if ((*(c+end) == delim || *(c+end) == '\0') && begin != end) {
            String *st = substring(s,begin,end-1);
            *(temp + arraycount) = st;
            begin = end + 1;
            arraycount++;
            temp = (String**)realloc(temp, 1+arraycount*sizeof(String*));
        }
    }

    arrayOfStructs = temp;
    return arraycount;
}

In main, when I get back split, all the String*'s that it points too are gone. When print_string gets an individual String* and tries to grab one of its members, a segmentation fault occurs. I don't understand why, because I feel like I allocate memory every time it is necessary, but I feel like I'm missing something. Also, when debugging, if I step through string_split, temp is produced exactly like I expect, so I think I'm just not malloc'ing somewhere where I'm supposed to and it's not a problem with the logic of the function. Here is the code in substring, although I'm pretty sure it works since I've been able to return String* from substring and pass them to print_string just fine.

String *substring(String *s1, int begin, int end) {
    String *s = (String*)malloc(sizeof(String));
    int length = 0;
    s->maxSize = 20;
    char *temp = (char*)malloc(20*sizeof(char));
    char *arr = s1->chars;

    int i;
    for (i=begin; i <= end; i++) {
        *(temp+length) = *(arr+i);
        length++;

        if (length == s1->maxSize-1) {
            s1->maxSize = s1->maxSize+20;
            temp = (char*)realloc(temp, s1->maxSize*sizeof(char));
        }
    }
    *(temp+length) = '\0';
    s->length = length;
    s->chars = temp;    
    return s;
}

Any help is greatly appreciated!

Upvotes: 0

Views: 110

Answers (2)

tesseract
tesseract

Reputation: 901

  String **temp = (String**)malloc(sizeof(String*));

  *(temp + arraycount) = st;

temp+arraycount is going to give you a random address in memory. temp contains the pointer you just malloced, which should point to another pointer.(which you have not initialised), but you are incrementing the pointer so you loose the location you just malloced.

temp is not pointing to consecutive memory, it specifically points to another pointer(which is 8bytes on a 64bit machine)

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409166

You need to pass the argument arrayOfStructs by reference and not by value. As C doesn't actually have proper references, you have to pass a pointer to the variable:

int string_split(String *s, char delim, String ***arrayOfStructs) {
    ...

    *arrayOfStructs = temp;
    return arraycount;
}

Call it using the address-of operator &:

num = string_split(st, ',', &split);

As it is now, you pass the argument by value, which means that the variable arrayOfStructs is just a local copy inside the function. Any changes to it is only made to the copy, and are lost once the variable goes out of scope when the function returns.

Upvotes: 3

Related Questions