-1

I need to realloc a string acquired via scanf("%ms", ...), does realloc automatically include the termination character \0 in my reallocated string? What's the behavior of reallocin this case?

Will it add \0 at the end of the reallocated string, or will it leave the \0 in the same position of the previous string, adding uninitialized memory after \0?

For example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char *string = NULL;
    char *p = NULL;
    int length = 0;
    //This should automatically add \0 at the end, if i'm not wrong
    scanf("%ms", &string);
    length = strlen(string);
    p = realloc(string, sizeof(char) * (length + 10));
    if (p != NULL) {
       string = p;
       p = NULL;
    }
    free(string);
    return 0
}

PS: I used strlen() over the string like here: strlen with scanf("%ms"...)

chqrlie
  • 114,102
  • 10
  • 108
  • 170
Mattia Surricchio
  • 1,064
  • 2
  • 14
  • 38

3 Answers3

3

realloc doesn't know/care about null bytes or whatever else is stored in the given object. It simply guarantees that the old content is preserved/copied to in the new object it returns (assuming the realloc call succeeds). As long you have previously added it, it'll be there after realloc too. And in your case, null byte's there (assuming scanf succeeded), so it'll be there after realloc too.

However, note that if you shrink the object with realloc, then only the contents up to the specified size will be preserved - in this case, you may not have the null byte after realloc.

chqrlie
  • 114,102
  • 10
  • 108
  • 170
P.P
  • 112,354
  • 20
  • 166
  • 226
2

realloc() is not just for characters or integers. It will free the previous memory allocation automatically and then reallocate the requested memory.

Will it add \0 at the end of the reallocated string?

It's out of the question.

Will it leave the \0 in the same position of the previous string, adding uninitialized memory after \0?

realloc() doesn't overwrite old contents, not prior memory place. It doesn't touch its content, just moves to and reallocates new memory chunk(s).

snr
  • 16,197
  • 2
  • 61
  • 88
  • So the answers is "yes" to my second question? I'll end up with the same identical string as before + uninitialized memory after \0? – Mattia Surricchio Aug 09 '18 at 11:29
  • @AnttiHaapala by the way, you have changed your profile picture, hamburgers – snr Aug 09 '18 at 11:38
  • @snr not hamburgers, they were Finnish "synonym rolls" ;) – Antti Haapala -- Слава Україні Aug 09 '18 at 12:43
  • Detail: "realloc() doesn't overwrite old contents." is not specified true when the allocation shrinks. Even if the same pointer returned, the old contents beyond the new allocation size may or may not be overwritten. IAC, attempting to access those "beyond" bytes is UB. – chux - Reinstate Monica Aug 09 '18 at 13:31
  • @chux When I'm saying old contents that it is the content which includes old one but in new location. Still isn't there a guarantee of not alteration? And what does _IAC_ mean sir? – snr Aug 09 '18 at 14:18
  • There is not a _guarantee of not alteration_ for the portion of memory beyond the end of a reduced memory `realloc()`. IAC --> "In any case". – chux - Reinstate Monica Aug 09 '18 at 14:44
  • @chux so, is usage of _realloc()_ always risky since the data may corrupt? – snr Aug 09 '18 at 14:45
  • @snr `realloc()` is not risky. When a re-allocation shrank memory, why should code care if the data beyond the new smaller size is not altered? – chux - Reinstate Monica Aug 09 '18 at 14:53
  • @chux actually it is what I try to explain but my explanation might somewhat misleading. Of course, that's right!, sir. Thanks – snr Aug 09 '18 at 15:03
0

realloc() - Changes the size of the memory block pointed to by ptr.

The content of the memory block is preserved up to the lesser of the new and old sizes, even if the block is moved to a new location. If the new size is larger, the value of the newly allocated portion is indeterminate.

You need to allocate the memory for string, using malloc() before using realloc(). scanf() will fail to write memory to NULL pointer (string value).