When should malloc be used in C, and when not?

I understand how malloc () works. My question is: I will see things like this:

#define A_MEGABYTE (1024 * 1024) char *some_memory; size_t size_to_allocate = A_MEGABYTE; some_memory = (char *)malloc(size_to_allocate); sprintf(some_memory, "Hello World"); printf("%s\n", some_memory); free(some_memory); 

I skipped error checking for brevity. My question is, can you just do this by initializing a pointer to some static storage in memory? perhaps:

 char *some_memory = "Hello World"; 

At what point do you really need to allocate the memory yourself, and not declare / initialize the values ​​that need to be saved?

+82
c memory-management memory
Dec 26 '09 at 16:51
source share
6 answers
 char *some_memory = "Hello World"; 

creates a pointer to a string constant. This means that the string "Hello World" will be somewhere in the read-only part in memory, and you have a pointer to it. You can use the string as read-only. You cannot make changes to it. Example:

 some_memory[0] = 'h'; 

Asks for problems.

On the other hand,

 some_memory = (char *)malloc(size_to_allocate); 

allocates a char array (variable), and some_memory points to allocated memory. Now this array is read and written. Now you can:

 some_memory[0] = 'h'; 

and the contents of the array will change to "hello world"

+112
Dec 26 '09 at 17:02
source share

For this exact example, malloc is of little use.

The main reason malloc is required is when you have data that must have a different lifespan than the code area. Your code calls malloc in one routine, stores a pointer somewhere, and ultimately calls in another routine.

The second reason is that C has no way of knowing if there is enough free space on the stack for distribution. If your code should be 100% reliable, it’s safer to use malloc, because then your code may know that the selection failed and process it.

+27
Dec 26 '09 at 16:57
source share

malloc is a great tool for allocating, reallocating, and freeing memory at runtime compared to static declarations like your hello world example, which are processed at compile time and therefore cannot be resized.

Malloc is always useful when you are dealing with data of arbitrary size, such as reading the contents of a file or working with sockets, and you are not aware of the length of the data being processed.

Of course, in a trivial example like the one you gave, malloc is not a magical “right tool to work properly”, but for more complex cases (for example, to create an arbitrary size at runtime), only the way.

+14
Dec 26 '09 at 17:01
source share
 char *some_memory = "Hello World"; sprintf(some_memory, "Goodbye..."); 

is illegal, string literals const .

This will allocate a 12-byte char array on the stack or globally (depending on where it was declared).

 char some_memory[] = "Hello World"; 

If you want to leave room for further manipulations, you can specify that the size of the array should be larger. (Please do not push 1MB onto the stack.)

 #define LINE_LEN 80 char some_memory[LINE_LEN] = "Hello World"; strcpy(some_memory, "Goodbye, sad world..."); printf("%s\n", some_memory); 
+5
Dec 26 '09 at 17:00
source share

One of the reasons you need to allocate memory is if you want to change it at run time. In this case, you can use malloc or a buffer on the stack. A simple example of assigning a "Hello World" to a pointer defines a memory that "normally" cannot be changed at run time.

+4
Dec 26 '09 at 16:57
source share

If you do not know the exact size of the used memory, you need dynamic allocation ( malloc ). For example, a user may open a file in your application. You will need to read the contents of the file in memory, but, of course, you do not know the file size in advance, since the user selects the file in place at run time. So basically you need malloc when you don’t know in advance the size of the data you are working with. At least one of the main reasons for using malloc . In your example with a simple line that you already know, size at compile time (plus you don't want to change it), it doesn't make much sense to dynamically highlight this.




A little off topic, but ... you have to be very careful not to create memory leaks when using malloc . Consider this code:

 int do_something() { uint8_t* someMemory = (uint8_t*)malloc(1024); // Do some stuff if ( /* some error occured */ ) return -1; // Do some other stuff free(someMemory); return result; } 

You see what is wrong with this code? There is a conditional return expression between malloc and free . It may sound good at first, but think about it. If there is an error, you will return without freeing the allocated memory. This is a common source of memory leaks.

Of course, this is a very simple example, and it is very easy to see an error here, but imagine hundreds of lines of code littered with pointers, malloc s, free s and all kinds of error handling. Things can get really dirty very quickly. This is one of the reasons why I prefer modern C ++ over C when applicable, but this is a whole topic.

Therefore, whenever you use malloc , always make sure your memory is as free as possible.

+3
Apr 24 '16 at 12:19
source share



All Articles