0

this function get an memory allocated input(with size : 1 bytes) from user and put it in heap data. it works correctly in function but when this function ends and come back to main, input will be corrupted. it happens when re-allocate function change the address of strings in heap memory. can anyone help me to fix it?

int main() {
    char* input = (char*)malloc(sizeof(char));
    example(input);
    printf("%s", input);
}

   
void example(char* input) {
    int i = 0;
    char* a = "qweqeqweqweqweqweqwasdfsdfsdgasdgg";
    for (int i = 0; i < 20; i++) {
        input = (char*)realloc(input, sizeof(char) * i + 1);
        input[i] = a[i];
    }
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    `example` is only getting a copy of the pointer `input`. `input` in `main` will not change when you change `input` in `example`. If you run your program in a debugger, you can see that. Side note: if `realloc` fails the old pointer will still be valid, but when you write `p = realloc(p,...)` you lose the old value and thus have a memory leak. – Werner Henze Jan 30 '21 at 19:43
  • The duplicate question has two good answers. The accepted answer gives one of two ways of solving the problem; the second answer outlines both ways of solving the problem (and is arguably the better answer, therefore). Basically, you either have the called function return the reallocated (or just allocated) pointer, or you pass a pointer to the pointer that will be (re)allocated. – Jonathan Leffler Jan 30 '21 at 20:01

2 Answers2

2

The realloc function can return a pointer that was different from what was passed in. If that happens, the copy of input you have in the main function is invalid.

You can fix this by having example return the modified pointer and assigning to back to input in the main function. Also:

  • Don't cast the return value of realloc
  • If realloc fails the original pointer is still valid, so assign to a temporary and check the return value
  • You need to add a terminating null byte to the string and allocate additional space for it.

So your function would become this:

char *example(char* input) {
    int i = 0;

    char* a = "qweqeqweqweqweqweqwasdfsdfsdgasdgg";
    for (int i = 0; i < 20; i++) {
        char *tmp = realloc(input, i + 1 + 1);
        if (!tmp) {
            perror("relloc failed");
            free(input);
            exit(1);
        }
        input = tmp;
        input[i] = a[i];
    }
    intput[i] = 0;
    return input;
}

And you call it like this:

input = example(input);

You should also move the definition of example to before main, that way it can be called correctly.

dbush
  • 205,898
  • 23
  • 218
  • 273
1

The way you call realloc is wrong. You should use a temporary variable to save the pointer because if realloc fails you will loose the reference the original memory block.

char *example(char* input);

int main(void) 
{
    char *input = malloc(sizeof(*input));
    char *tmp;
    if((tmp == example(input))) input = tmp;
    printf("%s", input);
}

   
char *example(char* input) {
    int i = 0;
    char* a = "qweqeqweqweqweqweqwasdfsdfsdgasdgg";
    for (int i = 0; i < 20; i++) 
    {
        char *tmp = realloc(input, sizeof(*input) * (i + 2));
        if(tmp)
        {
            input = tmp;
            input[i] = a[i];
            input[i + 1] = 0;
        }
        else
        {
            /* handle allocation error */
        }
    }
    return tmp;
}

You can also use pointer to pointer but you need to save the original pointer to avoid potential memory leak:

int main(void) 
{
    char *input = malloc(sizeof(*input));
    char *tmp = input;

    example(&tmp);
    if(tmp) input = tmp;
    printf("%s", input);
}

   
void example(char** input) {
    int i = 0;
    char* a = "qweqeqweqweqweqweqwasdfsdfsdgasdgg";
    for (int i = 0; i < 20; i++) 
    {
        *input = realloc(*input, sizeof(*input) * (i + 2));
        if(*input)
        {
            *input = tmp;
            (*input)[i] = a[i];
            (*input)[i + 1] = 0;
        }
        else
        {
            /* handle allocation error */
        }
    }
}

Another problem in your code: you do not null terminate your string. You need to read warnings. You have more issues in your code - for example, you call function without prototype.

0___________
  • 60,014
  • 4
  • 34
  • 74