Reputation: 3170
Suppose I have a char pointer which points to some string in memory.
and suppose I want to copy that string to some other place in memory.
void cpy(char **dst, char *src)
{
*dst = (char *) realloc(*dst, strlen(src) + 1);
memcpy(*dst, src, strlen(src) + 1);
}
(Assume memory allocation is successful, and src
is not NULL)
What if I call this function like this:
char *str = malloc(14);
memcpy(str,"hello, world!", 14);
cpy(&str,str+7);
Now I would expect srt
to point to the string "world!"
(Which it does in my tests).
But what concerns me is that in this call to cpy
, *dst
and src
actually point to different locations of the same string. And, when calling realloc
on *dst
, it's possible that this memory will be freed. But in the next line I'm trying to copy from that place with memcpy
.
So the questions is: Is there something wrong with it?
Or to put it another way - is it okay to free memory, and use it immediately afterwards?
Thanks.
Note: The example was updated so that realloc
is called on memory that was obtained with malloc
.
Upvotes: 1
Views: 130
Reputation: 2970
The implicit assumption in your example is that it is permitted for cpy
to free memory it didn't allocate. It's kind of a dodgy assumption, but as long it's intentional, that's OK. Use malloc
and free
separately rather than realloc
in that case:
void cpy(char **dst, char *src)
{
// obtain completely new memory (realloc might do this anyway)
char* new = malloc(strlen(src) + 1);
// duplicate the string
memcpy(new, src, strlen(src) + 1);
// release the original memory now that we know we are done with it
free(*dst);
// indicate where to find the new string
*dst = new;
}
This still isn't a great idea, because there's no way to know what other variables might be pointing at that memory that you're free
ing, but if you have a way to make that guarantee, this is the kind of code you need.
Upvotes: 1
Reputation: 476980
Everything is wrong with this. It is outright undefined behaviour to call realloc
on a pointer that was not obtained with malloc
etc.
As @Daniel Fischer points out, it is also undefined behaviour to use memcpy
on overlapping regions of memory (in which case you should use memmove
), so you have to be careful.
Update: After your substantial edit, the question is quite different. It is now equivalent to this condensed version:
char * s = malloc(14);
strcpy(s, "hello, world!");
char * p = realloc(s, 14);
memcpy(p, s, 14);
This is also undefined behaviour, because you are not allowed to access the memory pointed to by s
anymore after a successful realloc
, and you're not allowed to access the memory pointed to by p
after an unsuccessful realloc
.
Upvotes: 9