noe
noe

Reputation: 43

When is it necessary to allocate dynamic memory using malloc on pointers?

I am having trouble fully understanding the malloc() function in C, more precisely when it is necessary to use it.

When I declare a pointer to a global struct like so,

struct Position* currentPositionPtr;

do I need to assign dynamic memory to it using malloc to initialize it? Or is it good practice to simply assign a pointer of the struct to it later on when needed like e.g.

currentPositionPtr = getPosition();

where getPosition() returns a pointer to the "struct Position".

Upvotes: 2

Views: 2086

Answers (6)

Eric Finn
Eric Finn

Reputation: 8995

malloc (or another memory-allocating function) is needed whenever you need the system to give memory to you.

So yes, when you do

struct Position* currentPositionPtr;

you will either need a call to malloc():

currentPositionPtr = malloc(sizeof(struct Position));

or to assign the pointer to the address of an already allocated block of memory:

struct Position globalPos;

void func(void) {
    struct Position pos;
    struct Position* currentPositionPtr = &pos; //ok
    struct Position* globalPosPtr = &globalPos; //also ok
    ...
}

because all you are doing is declaring the pointer, not reserving space for a structure.

However, if your pointer is global, assigning it to stack-allocated memory is potentially dangerous. Consider the following:

struct Position *globalPosPtr = NULL;

void foo(void) {
    struct Position pos;
    globalPosPtr = &pos;
    //can dereference globalPosPtr with no problems here
    ...
}

void bar(void) {
    foo();
    //globalPosPtr is invalid here
    ...
}

As for your question about having another function that returns a pointer:

getPosition() will need to use malloc or some other memory-allocating function itself. So doing that is perfectly fine, and can make sense if you generally want to initialize values in the struct to some values. However, remember that, even if you called malloc inside some other function, you will need to free the memory when you are done using it to prevent memory leaks.

To answer the question in the title, whenever you declare something as a pointer, you need to give it something to point at if you want to use it. If you want it to point at a new thing, you need to dynamically allocate it with malloc() or a related function.

Upvotes: 2

uni
uni

Reputation: 117

There are few simple things to understand :

  1. malloc() simply returns you memory from heap and its the responsibility of the user process to FREE this chunk of memory by calling the FREE system call.

  2. When at coding time you know, that you need to deal with fixed amount of memory say a struct ,an array then you can satisfy the memory requirement of the process with local variables and Global Variables.

And from your query,it seems that you are confused when you have to deal with malloc and as a result pointers.

  1. You need a pointer to hold the address of the memory allocated by malloc system call.
  2. The pointer not necessarily point to the memory allocated by malloc,it can be any valid memory like:

     int a =2;
     int *ptr; 
     ptr = &a;
    

So here, ptr points to memory location NOT allocated by malloc.

Conversely, you can do

   int *ptr;  
   ptr = (int*)malloc(sizeof(int));

In your case a pointer currentPositionPtr to struct can point to the address of Global/local variable provided the memory address remains valid throughout the access of this pointer.

I hope this simplifies things.

Upvotes: 0

user529758
user529758

Reputation:

What does getPosition() do?

If it returns a valid pointer to struct Position, then of course you don't need to allocate memory for the struct twice. I hope your function does not look like this:

struct Position *getPosition()
{
    struct Position p = { x, y };
    return &p;
}

since this would exhibit undefined behavior (by returning a pointer to a block scope automatic object). Generally, you rather return an already malloc()ated pointer instead:

struct Position *getPosition()
{
    struct Position *p = malloc(sizeof(*p));
    p->x = 42;
    p->y = 1337;
    return p;
}

Then, again, you don't need an additional call to malloc().

If, however, it's not the called function who is responsible for the allocation, then, well... it's the caller who is:

void getPosition(struct Position *p)
{
    p->x = 42;
    p->y = 1337;
}

And in this latter case you would need to call it like this:

struct Position *p = malloc(sizeof(*p));
getPosition(p);

if you need your struct to survive function returns, or

struct Position p;
getPosition(&p);

if you don't.

Upvotes: 8

aah134
aah134

Reputation: 860

if you are using a struct with a known size, you dont have to use malloc to allocate the memory because memory is not changable between to different struct Position, however,

if within struct Position, you have a pointer to unknown size, depending on some user input, then you may use malloc to allocate that size of needed memory block.

also if you are allocating struct Position array, then

currentPositionPtr = malloc(sizeof(struct Position)*neededSize);

after you are done, you will have to delete the memory with

free (currentPositionPtr)

Upvotes: 0

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29213

Typically, malloc is used in these cases:

  1. When you want to allocate memory dynamically: In other words, when you don't know how much memory you're going to need. Or when you don't know when you'll stop needing it.
  2. When you want to allocate a very large amount of memory: The heap can grow very large, but the stack is much more constrained. Allocating something very large on the stack could lead to a stack overflow (hey! That's the name of the site!). Of course, such sizes are implementation specific, hence the rather subjective phrase "very large".
  3. When you want your allocated memory to be accessible externally: If other threads of your program need access to a piece of memory, allocating it on the stack of one thread would be a bad idea, because it could be overwritten as that thread moves on, and then everyone else would be looking at corrupted memory.
  4. Probably a couple of other cases too.

Upvotes: 1

James Manes
James Manes

Reputation: 526

It seems like you already know how malloc works, but I'll try to answer your question.

Whenever you malloc, just be sure to keep a pointer on it so that you may manipulate it (or free it). The pros of malloc is that it is dynamic. Instead of declaring an array, you can declare a linked list of malloc'd structs (for example) and use pointers to keep track of them. In this way you never run into a problem such as walking off of the array. Instead you can just ask for more space dynamically and free it later when needed.

Upvotes: 0

Related Questions