views:

35

answers:

1

Platform: Linux, OSX
Compiler: GCC

I've got a simple program which is currently confounding me - I know that I'm messing with a couple different kinds of arrays/pointers to produce this problem - its intentional - I'm trying to understand it.

The code as listed will compile and run as expected, but changing data4 in the call to strsep(&data4, "e"); to data1 or data3 causes a segmentation fault. I would like to understand why.

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

int main(int c, char** v) {
    char* data1 = "hello\0";
    char* data2 = strdup(data1);
    size_t sz = strlen(data1);
    char data3[sz+1];
    char* data4;

    memset(data3, 0, sz+1);
    data4 = strncpy(data3, data1, sz);
    data4[sz] = '\0';

    char* found = strsep(&data4, "e");

    if (found == NULL) {
        printf("nothing found\n");
    } else {
        printf("found e\n");
    }

    return 0;
}
+5  A: 

changing data4 in the call to strsep(&data4, "e"); to data1 or data3 causes a segmentation fault.

In this case:

char* found = strsep(&data1, "e");

the string pointed to by data1 is a literal so it cannot be changed. When strsep() tries to place a '\0' into it, segfault.

in the other case:

char* found = strsep(&data3, "e");

data3 is an array, not a pointer (even though arrays easily evaluate to pointers, they are not actually pointers), so strsep() cannot update the value of the pointer which is what it tries to do once it finds the token. I get the following warning from gcc attempting to point this out:

test.c:17: warning: passing argument 1 of 'strsep' from incompatible pointer type
Michael Burr