-1

I'm trying to reallocate memory using the realloc function, I saw that you need to use malloc before but I don't understand if you MUST use it because let's say I'm creating the following string:

char string[] =  "fun";

would the realloc function work if I try to add more space?

that brings me to my question, I'm trying to simply add one letter at the end of the string, lets say 'p', but for some reason the program crushes on the realloc line every time I run it.

Here is my full code:

int main()
{
char string[] =  "fun" ;
str_func(string);
printf("%s", string);
return 0;
} 

void str_func(char* str)
{
str = (char*)realloc(str, strlen(str) + 2);
strcat(str, "p");
}

I also tried making a pointer to 'string' and sending the pointer, which results the same thing.

yarin Cohen
  • 995
  • 1
  • 13
  • 39
  • 2
    No, you can only `realloc()` something you've got from `malloc()` or `calloc()` (or from a following `realloc()`) or `NULL`. – pmg Nov 25 '20 at 12:29
  • so you have to use malloc() before? – yarin Cohen Nov 25 '20 at 12:30
  • `realloc(NULL, 42)` is ok, no need to use `malloc()` before in this case. – pmg Nov 25 '20 at 12:31
  • Yes. Don't mix stack-allocated arrays (normal arrays) and heap-allocated arrays (`malloc` and `realloc`). – Roy Avidan Nov 25 '20 at 12:31
  • Anyway, the function throws away the reallocated pointer, even if it could be reallocated. – Weather Vane Nov 25 '20 at 12:32
  • 1
    Does this answer your question? [C: Expanding an array with malloc](https://stackoverflow.com/questions/2748036/c-expanding-an-array-with-malloc) – Roy Avidan Nov 25 '20 at 12:33
  • Beside the problem ( realloc without malloc) mentioned in above comments, the code has other problem -- need to return the 'str' pointer from the str_func function or pass &str ( char**) as argument and assign content of it to reallocation output. – gobinda Nov 25 '20 at 12:46
  • https://en.cppreference.com/w/c/memory/realloc – klutt Nov 25 '20 at 13:10

3 Answers3

1

would the realloc function work if I try to add more space?

No, because that array is no allocated on the heap - in your case it is very likely allocated on the stack and can't get resized. Simply put: realloc doesn't recognize the pointer and doesn't know what to do with it, but tries to do something anyway, hence the crash.

You can only call realloc on a pointer that was previously passed to malloc, or on a null pointer. That's just how these functions work.

For details, see What gets allocated on the stack and the heap?.

Lundin
  • 195,001
  • 40
  • 254
  • 396
1

I saw that you need to use malloc before but I don't understand if you MUST use it

If you need to use malloc before you can realloc something, then by definition you must only realloc things originally allocated with malloc.

You're trying to find some space between "need" and "must" that doesn't exist.

... for some reason the program crushes on the realloc

You already said you know you need to use malloc. Then you didn't use malloc, and you're asking why this is a problem. You could at least try doing the thing you "know" you need to do, to see if that solves the problem.

The program should probably look like

int main()
{
  /* array is an automatic local variable. It wasn't dynamically allocated
     in the first place, so can't be dynamically re-allocated either.
     You cannot (and don't need to) free it either, it just goes out of scope
     like any other automatic variable.
  */
  char array[] = "fun";

  /* you need to use malloc (or one of the other dynamic allocation functions)
     before you can realloc, as you said yourself */
  char *dynamic = malloc(1+strlen(array));
  memcpy(dynamic, array, 1+strlen(array));

  /* realloc can move your data, so you must use the returned address */
  dynamic = str_func(dynamic);
  printf("old:'%s', new:'%s'\n", array, dynamic);

  /* not really essential since the program is about to exit anyway */
  free(dynamic);
} 

char* str_func(char* str)
{
  char* newstr = realloc(str, strlen(str) + 2);
  if (newstr) {
    strcat(newstr, "p");
    return newstr;
  } else {
    /* we failed to make str larger, but it is still there and should be freed */
    return str;
  }
}

Your original condition isn't quite correct: actually the pointer passed to realloc

... must be previously allocated by malloc(), calloc() or realloc() and not yet freed with a call to free or realloc

[OR] If ptr is NULL, the behavior is the same as calling malloc(new_size).

Useless
  • 64,155
  • 6
  • 88
  • 132
0

The realloc function only works with things that were originally created with a small group of allocation functions (such as malloc, calloc, or realloc itself), or the null pointer. Since string is none of those things, your code is not well-defined.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953