I have a program in C using Solaris with VERY ancient compatibility it seems. Many examples, even here on SO, don’t work, as well as lots of code I’ve written on Mac OS X.
So when using very strict C, what is the safest way to pass strings?
I’m currently using char pointers all over the place, due to what I thought was simplicity. So I have functions that return char*, I’m passing char* to them, etc.
I’m already seeing strange behavior, like a char* I passed having its value right when I enter a function, and then the value being mysteriously gone OR corrupted/overwritten after something simple like one printf() or an malloc to some other pointer.
One approach to the functions, which I’m sure is incorrect, could be:
char *myfunction(char *somestr) {
char localstr[MAX_STRLENGTH] = strcpy(localstr, somestr);
free(somestr);
/* ... some work ... */
char *returnstr = strdup(localstr);
return returnstr;
}
This seems…sloppy. Can anyone point me in the right direction on a simple requirement?
Update
One example of a function where I am at a loss for what is happening. Not sure if this is enough to figure it out, but here goes:’
char *get_fullpath(char *command, char *paths) {
printf("paths inside function %s\n", paths); // Prints value of paths just fine
char *fullpath = malloc(MAX_STRLENGTH*sizeof(char*));
printf("paths after malloc %s\n", paths); // paths is all of a sudden just blank
}
Well-written C code adheres to the following convention:
errnowith an appropriate value (e.g. EINVAL).freeany of its parameters, and should onlyfreeobjects that it, itself, allocates withmalloc/calloc.const char*objects or aschar*objects, depending on whether the string is to be overwritten. If the string is not to be modified, thenconst char*should be used.char*) object is passed into a function, and that function is to overwrite, append, or otherwise modify the string, a parameter indicating the capacity of the string/buffer needs to be provided (so as to allow for dynamic buffer sizes and to avoid bufffer overflow).I should point out that in your example code, you are returning
localstrand notreturnstr. Consequently, you are returning an address of an object in the current function’s stack frame. The current function’s stack frame will disappear once the function has returned. Invoking another function immediately afterwards will likely alter the data in that location, leading to the corruption that you have observed. Returning the address of a local variable leads to “undefined behavior” and is incorrect.Edit
Based on your updated code (get_fullpath), it is clear that the problem is not in your function get_fullpath, but rather in the function that is calling it. Most likely, the
pathsvariable is being supplied by a function that returns the address of a local variable. Consequently, when you create a local variable within get_fullpath, it is using the same exact location on the stack that paths previously occupied. Since “paths” is aliasing “fullpaths”, it is basically overwritten with the address of the buffer that you’ve malloced, which is blank.Edit 2
I have created a C Coding Conventions page on my website with more detailed recommendations, explanations, and examples for writing C code, in case you are interested. Also, the statement that localstr is being returned instead of returnstr is no longer true since the question has last been edited.