Memory is not reallocating
Asked Answered
B

2

6

I'm in the middle of a project and I'm trying to use malloc() and realloc(). I know when I malloc, it works, but when I use realloc, it doesn't change the amount of alloced memory at all. I've always though that realloc will re-allocate your already malloced memory.

Here is what I have:

This include:

#include <stdlib.h>

I have a struct:

struct student {
    int age;
    int numOfClasses;
    int gender; //0 male; 1 female
} student;

When I want to make 7 of those structs using malloc, I will use this line of code:

student stud* = (structure*) malloc(7*sizeof(student));

This line works. That line of code takes the size of the structure and multiples that by 7. In short, this will grab enough memory to make an array of 7 structures.

Now, if I want to change that to 8, I would do this where A is the previous malloced memory, and B is the new malloced (or realloced) memory:

enter image description here

Here is how I have it in code:

stud = (student*)realloc(stud, 8*sizeof(student));

From what I know, realloc takes the variable in the second parameter and mallocs that amount of memory. Then, it takes the pointer (or previous malloced), and fills in the just malloced memory with as much as it can from the given pointer. Of course, the second parameter must be bigger than the previous malloced size, or stud will lose some memory on the end. Now this is where my problem is. When I call the line above, it doesn't change anything. The malloced array is still length of 7. I'm pretty sure, also, that I have enough memory to realloc.

Am I doing this right? Where could my problem be?

Blimey answered 8/3, 2013 at 13:0 Comment(2)
What makes you think the malloced array is still of length 7?Argumentation
This doesn't relate to your problem, but I think your structure has a perfect use for an enum.Taxicab
A
11

Your understanding of realloc's behaviour is nearly correct. It doesn't have to return a different pointer; it may be that there was enough unused memory after the initial block, so the heap manager can just return the same pointer back to you (but adjust its own internal state such that it knows the block is now bigger).

You have made one small mistake, though.

stud = (student*)realloc(stud, 8*sizeof(student));

Here you are replacing your stud pointer with the return value from realloc. If it happens to return NULL due to memory starvation, then you have lost your original stud pointer and the memory is leaked. You should use a temporary pointer instead.

tmp = realloc(stud, 8*sizeof(student));
if (tmp)
    stud = tmp;

Also note that you still have to actually put something in the eighth slot. After the realloc the eighth slot is valid allocated memory, but contains garbage until you store something meaningful in it.

Argumentation answered 8/3, 2013 at 13:3 Comment(9)
I'm pretty sure that there is enough memory to realloc.Blimey
OK, but you still haven't explained why you think the malloced array is still of length 7.Argumentation
That's the thing, I don't know why it isn't allocating from 7 to 8.Blimey
It is. Why do you think it isn't?Argumentation
You do realise you have to actually put something in the eighth slot, right? After the realloc the eighth slot is valid allocated memory, but contains garbage until you store something meaningful in it.Argumentation
@RobAveryIV ur comment shows that u didnt understand the answer: "I'm pretty sure that there is enough memory to realloc."Dejesus
Hold on. I think I'm confusing myself. There is enough memory to allocate. But when I call realloc, the size of stud is still showing a length of 7.Blimey
Show me exactly how you are calculating or displaying the size of the stud block.Argumentation
@RobAveryIV 1. You can never be sure that there is enough memory to allocate unless you write a program just for testing. 2. You still didn't tell what makes you think the length didn't change.Pharos
S
4

This should work, although I'd have these recommendations:

Don't cast the return from malloc. It's useless in C and may hide that you have forgotten to include <stdlib.h>.

Do not use ptr = realloc (ptr, ...) as this creates a memory leak in the case realloc returns NULL. Instead, use

if ((new_ptr = realloc (stud, 8 * sizeof (*stud))) != NULL) {
     stud = new_ptr;
} else {
     scream_and_die("out of memory");
}

And use sizeof (*stud), i.e. reference an expression using the pointer, not the type being pointed to (to be independent of the particular type of pointer you allocate). This way, when you rename the typedef, the malloc/realloc line needs no modification. In other words, Best Practice for Dynamic Memory Allocation in C is

#include <stdlib.h>
sometype *ptr;
...
ptr = malloc (N * sizeof *ptr);

for an array of N sometypes.

Salinometer answered 8/3, 2013 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.