Reputation: 43
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
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
Reputation: 117
There are few simple things to understand :
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.
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.
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
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
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
Reputation: 29213
Typically, malloc
is used in these cases:
Upvotes: 1
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