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

+2


source to share


7 replies


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;

}    

      

+6


source


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

.

+1


source


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

.

+1


source


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!)

0


source


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;
} 

      

0


source


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).

0


source


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,

0


source







All Articles