Confusion between passing and modifying char pointers in C (value reference)
I was wondering if you could help me with the C line problem that I don't quite understand. I have a function to which I am sending 3 char pointers. Inside this function, the char pointers are offset and changed correctly. However, when I return to the main function from which they are called, the specified functions do not change. Am I wrong? Here's an example of my code:
int main(void)
{
LPSTR path = (char*)malloc(strlen(START_PATH));
strcpy( path, START_PATH );
char* newstr = (char*)malloc(PATH_SIZE);
TrimVal(path, "*.*", newstr);
//Do Stuff
return 0;
}
void TrimVal(char* modify, char* string, char* newstr)
{
newstr[0] = '\0';
modify = strncat(newstr, modify, (strlen(modify) - strlen(string)));
return;
}
NOTE: Assume PATH_SIZE
size value and START_PATH
is char array
source to share
Wherein
modify = strncat(newstr, modify, (strlen(modify) - strlen(string)));
You are modifying the pointer, not what the pointer points to.
When you go path
to TrimVal. It will be in memory path
, for example. 0x12345
When you execute modify =
, you say, change the local variable modify
to a new memory location, eg. 0x54321
When you go back to home it only has a pointer to 0x12345 and when it looks there nothing has changed.
You can easily fix your problem by doing
{
...
TrimVal(&path, "*.*", newstr);
...
}
void TrimVal(char** modify, char* string, char* newstr)
{
newstr[0] = '\0';
*modify = strncat(newstr, *modify, (strlen(*modify) - strlen(string)));
return;
}
source to share
void TrimVal(char* modify, char* string, char* newstr)
Changing values modify
, string
or newstr
within a function, TrimVal()
does not affect the variables in the calling function.
Changes to the content modify
, string
or newstr
inside the function, TrimVal()
will be reflected in the variables in the calling function.
So,
void TrimVal(char* modify, char* string, char* newstr)
{
newstr[0] = '\0'; /* will be reflected in the calling function */
modify = "a new string"; /* won't be reflected */
}
I think your function, with a little code cleanup, could do what you want.
Oh ... and you have a memory leak with a variable path
: you malloc some space for it and immediately lose the address of that space by assigning a different value to the variable path
.
source to share
A few points in addition to many other good points raised in this thread:
LPSTR path = (char*)malloc(strlen(START_PATH));
If it's C, you don't have to supply a return value malloc
. (See C FAQ 7.7b .
More importantly, it strlen
does not include termination \0
in its calculation. So the memory path
points to one character less than the required amount of memory to hold the START_PATH
plus \0
. Therefore:
strcpy(path, START_PATH);
invokes undefined behavior by writing one of them to the memory it points to path
.
source to share
If you expect your char * variable to be changed in a function and you want to follow the reference, you need to pass it as char *. Remember you are passing a pointer by reference, so an extra layer of indirection must be added (passing char passes anything by reference - one character!)
source to share
C really has no cross-referencing. This is where you pass pointers by value. A string in C is represented by a pointer to char. So, in the TrimVal function , you can change the contents of the string (i.e., the sharpened data) but not the pointer itself.
strncat changes the contents of the first parameter and returns the same value.
If you want to change the value of a path inside TrimVal , you must pass a pointer to a pointer, for example:
...
TrimVal(path, "*.*", newstr);
...
void TrimVal(char** modify, char* string, char* newstr)
{
newstr[0] = '\0';
*modify = strncat(newstr, *modify, (strlen(*modify) - strlen(string)));
return;
}
source to share
I see a problem with the first two statements. You declare the path as a char pointer and allocate memory for it, which is stored in that address holder. In the next statement, you change the value in the path to point to the beginning of the char array, START_PATH. You have lost your allocated memory.
Also, strncat does not call malloc for concatenation. You are expected to go into a buffer large enough to hold the concat and this is a potential security risk (buffer overflow).
source to share
Just one comment about your style of discarding the return type of calling malloc. When dropped, this can hide errors.
This will be a much better style.
Include stdlib.h and try making the call to malloc as type independent.
char *ptr_char = NULL;
ptr_char = malloc(sizeof(*ptr_char));
Hope it helps,
source to share