views:

91

answers:

3

Hello,

I'm trying to define a path at compile time by passing:

-DDCROOTDEF='"/path/to/stuff"'

on the compile line. I then try to get use this in the code like:

char * ptr_path;  
strcpy(ptr_path, DCROOTDEF);
strcat(ptr_path,"/MainCommons/CommonLib/fonts/Arial.ttf");
char *pftf=ptr_path;
gdImageStringFT(pimg,brect,iclr,pftf,pts,ang,ixp,iyp, (char *)cbuf);

Which gives me a segmentation fault. However, if I try to print the string first:

char * ptr_path;
strcpy(ptr_path, DCROOTDEF);
strcat(ptr_path,"/MainCommons/CommonLib/fonts/Arial.ttf");
char *pftf=ptr_path;
printf("%s\n",pftf);
gdImageStringFT(pimg,brect,iclr,pftf,pts,ang,ixp,iyp, (char *)cbuf);

It works just fine. What intricacy of char pointer's am I missing here?

Thanks

+3  A: 
char * ptr_path;
strcpy(ptr_path, DCROOTDEF);

You never initialize ptr_path.

It doesn't work in the second code snippet, you are just getting unlucky and it appears to work. You're still using an uninitialized pointer and trying to write to who knows where in memory.

You need to initialize ptr_path to point to an array of char that is at least strlen(DCROOTDEF) + 1 in length. You also need to check the length of DCROOTDEF before copying its contents into the array to be sure that it is not too long. You can do so manually using strlen or you can use a length-checked copy function like strlcpy.

James McNellis
strlcpy is non-standard,isn't it?
Nyan
@Nyan: `strlcpy` is nonstandard. You can easily [find an implementation online](http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/lib/libc/string/strlcpy.c?rev=1.11;content-type=text/plain).
James McNellis
If it appears to work, then it works. One possible outcome of undefined behaviour is the behaviour you were aiming for in the first place. Sadly.
Philip Potter
+1  A: 

The pointer ptr_path is not initialized to point at writable memory, which is why dereferencing it using strcpy() is crashing.

You need to call e.g. malloc() to get the space, first:

char * ptr_path = malloc(PATH_MAX);

Or something like that.

unwind
and you need to `free()` the memory when you've finished with it, too.
Philip Potter
+1  A: 

In

char * ptr_path;
strcpy(ptr_path, DCROOTDEF);
strcat(ptr_path,"/MainCommons/CommonLib/fonts/Arial.ttf");

the pointer is not bound to a legally allocated block of memory, so your program runs into undefined behavior. You need to allocate a buffer first - for example by using malloc(). Be sure that the buffer is large enough to hold the resulting string together with the terminating null character.

sharptooth