7

I am wondering what is the right/standard way to use malloc and free. Is it needed to set pointer NULL after free? Basically, which of the two following ways is correct?

double* myPtr = (double*)malloc(sizeof(double)*5);
.....
free(myPtr);

or

double* myPtr = (double*)malloc(sizeof(double)*5);
.....
free(myPtr);
myPtr = NULL;

Or it should be other ways to use malloc and free? Thanks.

Maxim Masiutin
  • 3,991
  • 4
  • 55
  • 72
Ono
  • 1,357
  • 3
  • 16
  • 38
  • 3
    You have to specify, either C or C++ ? – haccks Jul 04 '14 at 13:30
  • Setting the pointer to NULL does "help" in the situation where your workflow or a bug might try to free the buffer more than once. – Joe Jul 04 '14 at 13:32
  • I would guess that scope would answer a lot of those questions. If they're local variables, the variable will disappear when the frame is popped off the stack. – duffymo Jul 04 '14 at 13:32
  • 3
    If this is C++, the answer is usually don't use `malloc` or `free`. – chris Jul 04 '14 at 13:35
  • Thank you all of you. I really feel I learn about something that seems so straightforward but can be tricky many occasions. – Ono Jul 04 '14 at 13:51
  • For C, [please don't cast the return value of `malloc()`](http://stackoverflow.com/a/605858/28169). I know simonc mentioned this below, but the linked-to answer has more words. – unwind Jul 04 '14 at 13:57
  • I see. I am using C++, so I guess it should be fine? – Ono Jul 04 '14 at 14:01
  • 1
    @Ono If you are using C++ then don't tag C ! – P.P Jul 04 '14 at 16:31
  • @BlueMoon Care to elaborate a little? So don't use malloc you mean? If so what should I use? – Ono Jul 04 '14 at 18:49

7 Answers7

13

Both are fine. The only difference is that the former approach would crash if you tried to free myPtr a second time.

Depending on the language you're using, the malloc line could be tidied up a little.

Using sizeof(*myPtr) is less prone to bugs when you later refactor. If you're using C, the cast is also unnecessary

double* myPtr = malloc(sizeof(*myPtr)*5);

As pointed out by WhozCraig, if you're using C++, there are much easier ways to allocate an array

 std::vector<double> ar(5);

gives you an array of 5 doubles that will grow its storage if required and automatically free its memory when it goes out of scope.

simonc
  • 41,632
  • 12
  • 85
  • 103
  • @WhozCraig Thanks for fixing that important/embarrassing typo! – simonc Jul 04 '14 at 13:36
  • 1
    +1. Also, since `sizeof` is not a function, you can drop the parentheses. I format it like `double *myPtr = malloc(5 * sizeof *myptr);`, i.e. constant/scaling factor before the `sizeof`. – unwind Jul 04 '14 at 13:56
  • 1
    @simonc =P glad to help, Followup to "If you're using C, the cast is also unnecessary.." - If you're using C++, the *`malloc`* itself is unnecessary =) `std::vector ar(5);`. – WhozCraig Jul 05 '14 at 05:45
9

There is no any need to set the pointer to NULL in statement

myPtr = NULL;

On the one hand this prevents the program from an execution error if you will try to free the pointer the second time. On the other hand it maybe hides the bug code where you try to free the pointer the second time.

So whether you need to set the pointer to NULL depends on the program design.

If you are speaking about C++ then it would be better if you would use never C functions malloc and free. Consider using of smart pointers as for example std::shared_ptr.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
4

Use of free:

free() only marks the memory chunk as free - there is no enforcement of this freeing operation. Accessing memory chunks that were previously freed is the cause of many memory errors for novices and experienced programmers. A good practice is that always nullify a pointer that was just freed.

In case of C, just remove the cast:

double* myPtr = malloc(sizeof(double)*5);
.....
free(myPtr);
myPtr = NULL; 
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 2
    The quoted passage is false; Ely has the correct answer with regards to nulling it. Things like `myPtr = NULL;` in such cases only give a false sense of confidence, and can easily hide errors. – James Kanze Jul 04 '14 at 14:28
  • @JamesKanze; Stated clear there that: `Accessing memory chunks that were previously freed`, that mean if you do not want to access it then no need to nullify. – haccks Jul 04 '14 at 14:37
4

Setting the pointer back to "NULL" will only be useful if you need to reuse it again later and run checks on it like "if(myPtr) { [...] }". If you don't plan on reusing this specific pointer, you can leave it to whatever his value is.

Ely
  • 1,189
  • 9
  • 12
2

What you write is correct (however in C you shouldn't cast the return value of malloc, but in C++ you must do the cast). You don't have to set myPtr to NULL after calling free. Just don't dereference the memory after if has been freed.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • I am learning C++ now to translate some C code. I just found out about having to cast `malloc(sizeof(int))` from `void*` to `int*` (or `double`). Nice to see it mentioned here. – N Altun Jul 09 '21 at 16:30
2

You are free to do with Your pointer anything. You don't MUST set it to NULL, but it's good if You don't want to get SEGFAULT for free.

Let see examples.

double * ptr = malloc(sizeof(double) * 42 );
ptr[0] = 1.2; // OK
free (ptr); // OK
ptr = malloc(sizeof(double) * 13); // It's OK. You don't need to set pointer to NULL

Let see some more examples.

void assign(ptr)
{
    if( ptr != NULL) ptr[0] = 1.2;
}

double * ptr = NULL;
assign(ptr); // All OK, method will not pass check
double * ptr = malloc(sizeof(double) * 42);
assign(ptr); // OK, method will pass check and assign
free(ptr);
// ptr = NULL; // If we don't do this ....
.... a lot of code and 666 lines below ... 
assign(ptr); // BAH! Segfault! And if You assign ptr=NULL, it would not a segfault
Arenim
  • 4,097
  • 3
  • 21
  • 31
1

It is best to avoid malloc/free if you can avoid it. You can avoid it if

  • the array or structure you are allocating is "small" (you can count the size on your fingers) and you know the size at compile time

  • the array is used and discarded in the local scope of your program

If these are true, don't use malloc/free, but just use local auto variables which are allocated from the stack instead of the heap.

For example, this is simpler and easier to maintain

 {
   double myPtr[5];
   ...
 }

than this

 {
   double* myPtr = (double*)malloc(sizeof(double)*5);
   ...
   free(myPtr);
 }

It's good practice to use stack variables when you can, because a stack never gets "fragmented" like a heap can. But of course, a stack can overflow, so don't put anything "big" on the stack. Knowing what is "big" is not an exact science; you should know what your stack size is beforehand.

Mark Lakata
  • 19,989
  • 5
  • 106
  • 123