Question

If I have a variable, str that I would like to allocate memory to on the heap, I would use malloc() like:

char* str = (char*)malloc(sizeof("Hello"));

malloc() is returning a void* pointer, which is the memory location where my memory is. So now, I can give it some data

str = "Hello";

So, the memory location is now full, with 6 bytes. Now, I want to increase its size, to contain the string "Hello World". So, I use realloc(). According to man, void* realloc(void *ptr, size_t size) will:

The realloc() function changes the size of the memory block pointed to by ptr to size bytes. 
The contents will be unchanged in the range from the start of the region up to the minimum of 
the old and new sizes. If  the  newsize is larger than the old size, the added memory will not 
be initialized.

So I assumed that it will return a void* to the new, now bigger memory location, which I can now fill with my new string, so going on the same logic to malloc():

str = (char*)realloc(str, sizeof("Hello World"));

But, this is where the problem is. This will cause:

*** Error in `./a.out': realloc(): invalid pointer: 0x0000000000400664 ***

And in valgrind

Invalid free() / delete / delete[] / realloc()

This suggests that there is something wrong with the pointer, str. So I decided to remove:

str = "Hello";

And it compiles fine, with the following code:

char* str = (char*)malloc(sizeof("Hello"));
str = (char*)realloc(str, sizeof("Hello World"));

I am aware of the fact that pointer to realloc() must come from malloc(), but simply assigning data to it shouldn't cause realloc() to fail, which suggects that I am doing something completly wrong.

So, what am I doing wrong?

And here is the code that fails:

char* str = (char*)malloc(sizeof("Hello"));
str = "Hello";
str = (char*)realloc(str, sizeof("Hello World"));
// str = "Hello World"; - this is what I would to be able to do.

Note: This code is something I have stripped down from a much larger program, just to demonstrate the problem I am having, so I have removed checks etc. Also, I am very new to C, so hence the really simple problem (sorry?), but after hours of work and research, I still can't figure out what I am doing wrong - It seems to work fine for everyone else!.

Était-ce utile?

La solution

In C you cannot copy around blocks of memory as you tried to do:

str = "Hello";

That is not a valid string copy; instead, it leaves your malloc'd memory unaccounted for ("leaked"), and changes the pointer 'str' to point to a hard-coded string.

Further, because str is now a pointer to a hard-coded, static string, you cannot realloc it. It was never malloc'd to begin with!

To fix this, you want to change: str = "Hello"; to this:

strcpy(str, "Hello");

Autres conseils

str = "Hello";

is the problem. You allocated a buffer and made str point to it. You then need to copy into that buffer. Like this:

strcpy(str, "Hello");

But instead you changed the value of the pointer.

When you call realloc, you must pass to realloc, a pointer that was created by an earlier call to malloc, realloc or similar. But you did not do that. Because you modified str.

malloc() is returning a void* pointer, which is the memory location where my memory is.

So far so good

So now, I can give it some data

str = "Hello";

You are right on being able to give that memory some data, but you are wrong on a way of doing it: you cannot reassign the pointer to a string literal - this would create a memory leak. Instead, you should copy the data into the memory block, like this:

strcpy(str, "Hello");

If you do an assignment instead of a copy, the pointer no longer points to something returned by malloc, making it illegal to pass that pointer to realloc.

This instruction:

str = "Hello";

doesn't allocate any memory in the heap.

char* str = (char*)malloc(sizeof("Hello"));

You are allocating memory dynamically to the str. Good. You are cast-ing the return value of malloc(), Not good.

str = "Hello";

You are trying to put the address of the static string "Hello" in str. Why? This is actually overwriting the memory address allocated by malloc(). What str contains is not a dynamically allocated pointer right now. It's a static address, which is not eligible for realloc()/ free() . Also, you are taking yourself into a zone of memory leak. What I think is you need strcpy() instead.

if you want to avoid the reallocation of memory issue use the function strdup :

char *str = strdup("hello");
str = strdup("hello word");

strdup returns a pointer to the storage space containing the copied string. If it cannot reserve storage strdup returns NULL.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top