You've forgotten to assign the new value to *s in the function that contains realloc().
void test(void) // Unaltered; still broken!
{
char *c = malloc(strlen("I like coffe") + 1);
strcpy(c, "I like coffe");
char **s = &c;
while (strlen(*s) < 25)
my_function(s);
}
void my_function(char **s) // Fixed one way
{
char *w = *s;
size_t len = strlen(w) + 1; // Define and initialize len
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
w = tmp;
*s = w; // Reassign to `*s`
}
Or, more simply:
void my_function(char **s) // Fixed another way
{
char *w = *s;
size_t len = strlen(w); // Define and initialize len
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
*s = tmp; // Reassign to `*s`
}
Assigning to w only sets the local variable which is a copy of *s; it does not reset the pointer in the calling code.
Note that even with this fix, the loop in test() is going to run a long time because nothing changes the length of the string in c. There's also another problem: you don't pass the address of s to my_function(), so my_function() can't modify s.
void test(void)
{
char *c = malloc(strlen("I like coffe") + 1);
strcpy(c, "I like coffe");
while (strlen(c) < 25)
{
my_function(&c);
strcat(c, "AZ"); // Grow string — not good in real code
printf("%2zu: <<%s>>\n", strlen(c), c);
}
}
void my_function(char **s)
{
char *w = *s;
size_t len = strlen(w) + 1; // Define and initialize len
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
*s = tmp; // Reassign to `*s`
}
This does away with the pointer to pointer to char in test(). If that's crucial, there's more thinking to be done.
Code not formally tested yet!
Code now tested — can you say "pig's ear"? Copy'n'paste of the wrong material made my test code fail. Here's the instrumented working version — valgrind gives it a clean bill of health.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void my_function(char **s)
{
char *w = *s;
size_t len = strlen(w) + 1; // Define and initialize len
printf("M1: %p: %2zu: <<%s>>\n", (void *)w, len, w);
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
*s = tmp; // Reassign to `*s`
printf("M2: %p: %2zu: <<%s>>\n", (void *)*s, strlen(*s), *s);
}
static void test(void)
{
char *c = malloc(strlen("I like coffe") + 1);
if (c == 0)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
strcpy(c, "I like coffe");
printf("T1: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c);
while (strlen(c) < 25)
{
my_function(&c);
printf("T2: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c);
if (c == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
strcat(c, "AZ"); // Grow string — not good in real code
printf("T3: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c);
}
free(c);
}
int main(void)
{
test();
return 0;
}
*s = tmprather than aw = tmpin your code. Also, if realloc fails (returns NULL), you would need to set *s to NULL.realloc()returns NULL, the original allocation is unchanged.wit would NOT be just a COPY of*s. When I add a character tow[p]it changes in *s aswell.my_functionthereallocwill free the memory pointed to by*s. So you need to have an*s = wat the end of that function to update the original pointer to the new memory. Better still, IMHO, forget the double pointer. Just return the relloced value from the function. Also, don't need to callmallocin the parent function.reallocwill handle a NULL first paramter by doing a malloc.