25

Say for instance I created a pointer newPtr and I use malloc(some size) and then later I use malloc(some size) again with the same pointer. What happens? Am i then creating a second block of memory the same size of the first one? Does newPtr point to the same address?

Example:

int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = malloc(10 * sizeof(int));
Ace
  • 462
  • 4
  • 10
  • 17
  • 2
    The key point for you to learn is that one does not "use malloc on a pointer" – David Heffernan Oct 17 '13 at 19:26
  • The reason I ask is I'm trying to understand linked lists. The pointer points to a struct. Should'n I use malloc then? – Ace Oct 17 '13 at 19:32
  • Pointers and malloc are all well and good, the problem is that using "malloc on a pointer" is not what you are doing. The pointer can point to whatever you want it to, and `malloc` returns an address to where it allocated the memory as you requested. – Henrik Oct 17 '13 at 19:41

4 Answers4

29

Your program will have a memory leak. The first value of newPtr will be lost and you will not be able to free it.

Am i then creating a second block of memory the same size of the first one?

Yes. You are allocating a second object, distinct from the first one.

Does newPtr point to the same address?

No. The objects are distinct, so their address are distinct.

ouah
  • 142,963
  • 15
  • 272
  • 331
12

You're not actually using malloc on the same pointer. You're not giving the pointer to malloc at all. malloc always allocates new memory. So, the same thing happens as is the case with any variable assignment:

int a;
a = 14;
a = 20;

What happens to the 14? You can't access it anymore. In terms of malloc this means you no longer have a reference to the pointer it returned, so you'll have a memory leak.

If you actually want to use "malloc with the same pointer", you might be interested in the realloc function:

int *newPtr;
newPtr = malloc(10 * sizeof(int));
newPtr = realloc(newPtr, 10 * sizeof(int)); //*might leak memory*

From that link: realloc "changes the size of the memory block pointed to by ptr. The function may move the memory block to a new location (whose address is returned by the function)."


EDIT: Note that if realloc fails in the above, then it returns NULL, yet the memory pointed to by newPtr is not freed. Based on this answer, you could do this:

void *emalloc(size_t amt){
    void *v = malloc(amt);  
    if(!v) {
        fprintf(stderr, "out of mem\n");
        exit(EXIT_FAILURE);
    }
    return v;
}
void *erealloc(void *oldPtr, size_t amt){
    void *v = realloc(oldPtr, amt);  
    if(!v) {
        fprintf(stderr, "out of mem\n");
        exit(EXIT_FAILURE);
    }
    return v;
}

and then:

int *newPtr;
newPtr = emalloc(10 * sizeof(int));
newPtr = erealloc(newPtr, 10 * sizeof(int));
Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • In your example, what if `realloc` fails (returns `NULL`)? Memory leak! – ouah Oct 17 '13 at 19:58
  • @ouah: whoops, that sucks. good catch. Although if `malloc` and `realloc` fail you're probably boned, it's best to handle it explicitly. – Claudiu Oct 17 '13 at 20:08
4

These statements are not using malloc on newPtr.

The statement newPtr = malloc(10 * sizeof(int)); cause these operations:

  1. sizeof(int) is evaluated.
  2. That value is multiplied by 10.
  3. malloc is called, and that product is passed to it.
  4. malloc returns a value.
  5. That value is assigned to newPtr.

So you see, at step 3, newPtr is not involved in any way. Only after malloc is done is newPtr involved.

When you call malloc a second time, it has no way of knowing you are doing anything with newPtr. It merely allocates new space and returns a pointer to it. Then that new pointer is assigned to newPtr, which erases the old value that was in newPtr.

At that point, you have no way of knowing what the old value was. The space is still allocated, because it was not freed, but you do not have a pointer to it.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
3

You're not "using malloc on the same pointer". You're calling malloc() (which allocates space and returns a pointer to that space) and assigning its returned value to the same pointer object. (malloc itself has no idea what you're going to do with the result it returns.)

The second assignment, as with any assignment, will replace the previously stored value.

Which means that, unless you saved it elsewhere, you no longer have a pointer to the first allocated chunk of memory. This is a memory leak.

In addition, you should always check whether the result returned by malloc is a null pointer, and if so, take some corrective action. In the simplest case, that might be just printing an error message and terminating the program. You definitely should not assume the malloc call succeeded and then try to use the (nonexistent) allocated memory. (This isn't relevant to your question, but it's something that's easily missed, especially since allocation failures are rare in most contexts.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631