cppcoder
cppcoder

Reputation: 23095

Dynamic Memory Allocation

I have a small confusion in the dynamic memory allocation concept. If we declare a pointer say a char pointer, we need to allocate adequate memory space.

char* str = (char*)malloc(20*sizeof(char));
str = "This is a string";

But this will also work.

char* str = "This is a string";

So in which case we have to allocate memory space?

Upvotes: 1

Views: 1249

Answers (7)

Christian Rau
Christian Rau

Reputation: 45948

In the first example you're just doing things wrong. You allocate dynamic memory on the heap and let str point to it. Then you just let str point to a string literal and the allocated memory is leaked (you don't copy the string into the allocated memory, you just change the address str is pointing at, you would have to use strcpy in the first example).

Upvotes: 1

Ozair Kafray
Ozair Kafray

Reputation: 13529

I want to add to Alexey Malistov's Answer by adding that you can avoid memory leak in your first example by copying "This is a string" to str as in the following code:

char* str = (char*)malloc(20*sizeof(char));
strcpy(str, "This is a string");

Please, note that by can I don't mean you have to. Its just adding to an answer to add value to this thread.

Upvotes: 1

Magnus Hoff
Magnus Hoff

Reputation: 22089

String literals are a special case in the language. Let's look closer at your code to understand this better:

First, you allocate a buffer in memory, and assign the address of that memory to str:

char* str = (char*)malloc(20*sizeof(char));

Then, you assign a string literal to str. This will overwrite what str held previously, so you will lose your dynamically allocated buffer, incidentally causing a memory leak. If you wanted to modify the allocated buffer, you would need at some point to dereference str, as in str[0] = 'A'; str[1] = '\0';.

str = "This is a string";

So, what is the value of str now? The compiler puts all string literals in static memory, so the lifetime of every string literal in the program equals the lifetime of the entire program. This statement is compiled to a simple assignment similar to str = (char*)0x1234, where 0x1234 is supposed to be the address at which the compiler has put the string literal.

That explains why this works well:

char* str = "This is a string";

Please also note that the static memory is not to be changed at runtime, so you should use const char* for this assignment.

So in which case we have to allocate memory space?

In many cases, for example when you need to modify the buffer. In other words; when you need to point to something that could not be a static string constant.

Upvotes: 1

fredoverflow
fredoverflow

Reputation: 263078

Assigning to a char* variable makes it point to something else, so why did you allocate the memory in the first place if you immediately forget about it? That's a memory leak. You probably meant this:

char* str = (char*)malloc(20*sizeof(char));
strcpy(str, "This is a string");
// ...
free(str);

This will copy the second string to the first. Since this is tagged C++, you should use a std::string:

#include <string>

std::string str = "This is a string";

No manual memory allocation and release needed, and assignment does what you think it does.

Upvotes: 2

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145204

The presumably C++98 code snippet

char* str = (char*)malloc(20*sizeof(char));
str = "This is a string";

does the following: (1) allocates 20 bytes, storing the pointer to that memory block in str, and (2) stores a pointer to a literal string, in str. You now have no way to refer to the earlier allocated block, and so cannot deallocate it. You have leaked memory.

Note that since str has been declared as char*, the compiler cannot practically detect if you try to use to modify the literal. Happily, in C++0x this will not compile. I really like that rule change!

The code snippet

char* str = "This is a string";

stores a pointer to a string literal in a char* variable named str, just as in the first example, and just as that example it won't compile with a C++0x compiler.

Instead of this sillyness, use for example std::string from the standard library, and sprinkle const liberally throughout your code.

Cheers & hth.,

Upvotes: 3

Alexey Malistov
Alexey Malistov

Reputation: 26975

In first sample you have memory leak

char* str = (char*)malloc(20*sizeof(char)); 
str = "This is a string"; // memory leak

Allocated address will be replaced with new. New address is an address for "This is a string".

And you should change second sample.

const char* str = "This is a string";  

Because of "This is a string" is write protected area.

Upvotes: 7

Puppy
Puppy

Reputation: 146910

In the first example, you dynamically allocated memory off the heap. It can be modified, and it must be freed. In the second example, the compiler statically allocated memory, and it cannot be modified, and must not be freed. You must use a const char*, not a char*, for string literals to reflect this and ensure safe usage.

Upvotes: 2

Related Questions