Reputation: 1168
I have an unnamed structure called `FooStruct', and I wrote a function for it that initializes all its variables and also takes care of dynamic memory allocation.
I tried running this code, but it is not producing the results that I am expecting. For some reason, the variables are initialized correctly when inside the function, but then they change again once the block is exited.
A project that I'm working on requires that I use unnamed structs only. Why is this happening?
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int fooPrimitive;
} FooStruct;
void FooStructInit(FooStruct * ptr, int num) {
ptr = (FooStruct*)malloc(sizeof(FooStruct));
ptr -> fooPrimitive = num;
// Expected output: 5
// Actual output: 5
printf("ptr -> fooPrimitive: %d\n", (ptr -> fooPrimitive));
}
int main() {
FooStruct * ptr;
FooStructInit(ptr, 5);
// Expected output: 5
// Actual output: some random number
printf("FooStruct -> fooPrimitive: %d\n", (ptr -> fooPrimitive));
}
Upvotes: 0
Views: 42
Reputation: 15229
When you pass ptr
to FooStructInit
, it is copied and this copy is assigned the return value of malloc
then. This is called pass-by-value. Instead, pass a pointer to ptr
to actually write to ptr
and not just the passed argument:
void FooStructInit(FooStruct** ptr, int num) {
*ptr = malloc(sizeof(FooStruct));
(*ptr)->fooPrimitive = num;
// Expected output: 5
// Actual output: 5
printf("(*ptr)->fooPrimitive: %d\n", ((*ptr)->fooPrimitive));
}
int main() {
FooStruct* ptr;
FooStructInit(&ptr, 5);
// Expected output: 5
// Actual output: 5
printf("FooStruct->fooPrimitive: %d\n", (ptr->fooPrimitive));
}
Notes:
free
after malloc
malloc
Upvotes: 2
Reputation: 6088
C only has pass by value semantics, so when you pass a pointer to a function, the original value of the pointer is not changed, only the local copy is changed in the function.
The way to get around this is to pass a pointer to a pointer, so that you can change the value at the original memory location.
void FooStructInit(FooStruct **ptr, int num) {
*ptr = malloc(sizeof(FooStruct));
...
}
int main(void) {
FooStruct * ptr;
FooStructInit(&ptr, 5); /* get the address of the pointer */
...
}
Upvotes: 2