I have the following code:
#include <stdlib.h>
#include <stdio.h>
struct B
{
int _arr[5];
};
struct A
{
struct B *_pb_arr;
};
int main()
{
int i,j;
struct B b;
struct B *pb = (struct B*)malloc(sizeof (struct B));
*pb = b;
struct A a;
a._pb_arr = (struct B*)malloc(sizeof (struct B)*2);
a._pb_arr[0] = b; //first question
a._pb_arr[1] = *pb; //second question
for (i=0;i<2;++i)
{
for (j=0;j<5;++j)
{
a._pb_arr[i]._arr[j] = i;
}
}
struct A a2 = a;
for (i=0;i<2;++i)
{
for (j=0;j<5;++j)
{
printf ("%d, ", a2._pb_arr[i]._arr[j]);
}
}
return 0;
}
My question is: why on: a._pb_arr[0] = b;
The assignment is on stack.
and on the next line: a._pb_arr[1] = *pb
The assignment is on the heap?
It seems like a.pb_arr was allocated on the heap and each assignment is on the heap also.
Assignments aren't on the stack or heap, objects are.
Object a is on the stack because it's created like this:
struct A a;
To create objects on the heap, you have to allocate memory for them using malloc.
So although a is on the stack, a._pb_arr will be on the heap. You have to explicitly free the memory when you're done. Following the same reasoning, b is on the stack and pb is on the heap.
When you assign the objects in the array a._pb_arr, the values will be copied, but they still remain on the heap, since you allocated memory to a._pb_arr.
To prevent memory leaks, you have to use free for both a._pb_arr and pb.
Related
Hi I have a struct like this
struct small_struct {
int a;
int b;
}
struct big_struct {
struct *small_struct child;
}
I want to pass the pointer of big_struct as a parameter into a function in which child is initialized.
static int my_function(struct big_struct* s) {
if (certain_condition)
s->child = &(struct small_struct) {
.a = 1;
.b = 2;
}
}
However, when I do this and my_function is finished, the fields in s->child are often changed outside of the my_function. Would there be a way to keep a and b values as it was initialized inside my_function?
Thank you!
The problem is here:
s->child = &(struct small_struct) {
.a = 1;
.b = 2;
}
This creates the struct in the stack memory of the function, then assigns the s->child pointer to that memory. As soon as the function returns, that memory is no longer allocated to your struct. What you need to do is allocate heap memory for the structure, using malloc, which will stay allocated until it is free'd with a call to free:
static int my_function(struct big_struct* s) {
if (certain_condition)
{
//Allocate *heap* memory for the pointer
//This must be freed later!
//e.g free(s.child);
s->child = malloc(sizeof(struct small_struct));
s->child->a = 1;
s->child->b = 2;
}
Alternatively, depending on what you are trying to do, don't make child a pointer, that way the memory is already allocated in the instance of big_struct e.g.:
struct big_struct
{
struct small_struct child; //Note: not a pointer
};
static int my_function(struct big_struct* s) {
if (certain_condition)
{
//Memory for child member is already allocated
s->child.a = 1;
s->child.b = 2;
}
}
I have :
typedef struct a{
int var;
}aa;
typedef struct b{
aa *a;
}bb;
int main()
{
bb *b;
b->a->var;
return 0;
}
struct a nested in b.
How to initialize value for variable var using 2 pointers like this:
b->a->var;
?
Initialize b to a valid pointer.
Initialize b->a to a valid pointer.
Initialize b->a->var.
#include <stdlib.h>
typedef struct a{
int var;
}aa;
typedef struct b{
aa *a;
}bb;
int main(void)
{
bb *b;
/* initialize b */
b = malloc(sizeof(*b));
if (b == NULL) return 1;
/* initialize b->a */
b->a = malloc(sizeof(*b->a));
if (b->a == NULL)
{
free(b);
return 1;
}
/* initialize b->a->var */
b->a->var = 42;
/* free what are allocated */
free(b->a);
free(b);
return 0;
}
Struct a is not nested in struct b, but struct b contains a pointer to a a struct a object.
The two objects' pointers can be initialized independently E.g.: First allocate memory for a, then allocate memory for b, and finally assign the memory allocated for a to b->a.
However, it would be better to allocate memory for b first:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int var;
} aa;
typedef struct {
aa *a;
} bb;
int main() {
bb *b = (bb*) malloc(sizeof *b);
b->a = (aa*) malloc(sizeof *(b->a));
b->a->var = 5;
printf("%d\n", b->a->var);
free(b->a);
free(b);
}
(Checking malloc's return values omitted for brevity.)
Note the free'ing of memory in the reverse order. If b would have been free'd first, the pointer to a would have been lost.
Also, note how the typedef's do not declare an additional unused struct a and struct b.
I am having trouble figuring out how to make a hard-coded array heap allocated.
Imagine I have the structures:
struct my_struct
{
...
};
struct holder
{
my_struct *array_of_struct;
...
};
Now to create an instance of struct holder though, the array of struct my_struct has to be hard-coded, such as:
struct holder *new_holder()
{
struct holder *my_holder = malloc(sizeof(struct holder));
if (my_holder == NULL)
exit(-1);
struct my_struct arr[] = {mystruct_instace_1, mystruct_instance_2, ...};
holder->array_of_struct = arr;
return holder;
}
This assignment though wont work, because its pointing to arr which is stack allocated. How would I go about making this assignment of holder->array_of_struct heap allocated?
The super-lazy way to do it is just copy the array into a buffer from malloc(), as follows:
struct my_struct arr[] = {mystruct_instace_1, mystruct_instance_2, ...};
holder->array_of_struct = malloc(sizeof(arr));
assert(holder->array_of_struct);
memcpy(holder->array_of_struct, arr, sizeof(arr));
return holder;
By "super-lazy" I mean "minimum number of lines of code written".
I would like to allocate memory for arrays that are members of a struct I need to use, inside a function that takes the struct as an argument.
arg->A.size=(int*) malloc(N*sizeof(int));
will not compile (request for member 'size' is something not a structure.
arg->A->size=(int*) malloc(N*sizeof(int));
will throw a segmentation fault error
Any help will be appreciated.
Here is the code, thanks:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// struct A
struct A {
int dim; // dimensions
int* size; // points per dim array
double* val; // values stored in array
int total; // pow(size,dim)
};
// struct B that uses A
struct B {
int tag;
struct A* A;
};
int function_AB(struct B* B);
int main(void){
struct B B;
function_AB(&B);
return 0;
}
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A->size=(int*) malloc(N*sizeof(int));
return 0;
}
You simply haven't allocated memory for struct A *A. Before assigning anything to A->size you would first need to do something like
B->A = malloc(sizeof(struct A));
The second case is correct, but crashes because the A inside the B declared in main has not been assigned a value. You probably want something like
struct A A;
struct B B;
B.A = &A;
function_AB(&B);
When you have structure pointer in another structure, first you need to allocate memory for that. then allocate the memory for structure members!
struct B {
int tag;
struct A* A;
};
Here A is a pointer to a structure called A. First allocate memory for this, then allocate memory for the elements of struct A
arg->A = malloc(sizeof(struct A));
then do-
arg->A->size = malloc(N*sizeof(int));
Try the following changes in your int function_AB(struct B* arg)-
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A = malloc(sizeof(struct A)); // First allocate the memory for struct A* A;
arg->A->size = malloc(N*sizeof(int)); // Allocate the memory for struct A members
arg->A->val = malloc(N*sizeof(double));
// do your stuff
// free the allocated memories here
free(arg->A->size);
free(arg->A->val);
free(arg->A);
return 0;
}
And don't cast the result of malloc()!
This question already has answers here:
How to malloc inside a function and return pointer in C?
(3 answers)
C: adding element to dynamically allocated array
(3 answers)
Closed 8 years ago.
#include <stdio.h>
#include <stdlib.h>
struct myStruct
{
int number;
};
void
allocateMem(struct myStruct *struct1)
{
struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
}
int
main(int argc, char *argv[])
{
struct myStruct *struct1 = NULL;
allocateMem(struct1);
printf("number: %d\n", struct1->number);
return 0;
}
Hello citizens of StackOverflow, I seek your assistance.
What I am trying to do is allocate a struct using heap space rather than stack space; and I am trying to do the allocation inside of a function. No matter how much I mess with this I always get either a segmentation fault or several compiler warnings.
I'm doing something here incorrectly, but I can't figure out what, I've been all over StackOverflow and the general internet trying to find an example or post that relates to my issue but I have not found anything.
If you could tell me what I'm doing wrong, or just point me in the right direction I would be extremely grateful.
Thank you everyone for your quick and accurate replies. You were correct, I needed a pointer to a pointer, my code works now thanks to your help.
In this function,
void
allocateMem(struct myStruct *struct1)
{
struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
}
struct1 is passed by value. Any changes you make to it in the function are not visible from the calling function.
A better alternative:
struct myStruct* allocateMem()
{
struct myStruct *struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
return struct1;
}
Change the calling function to:
int
main(int argc, char *argv[])
{
struct myStruct *struct1 = allocateMem();
printf("number: %d\n", struct1->number);
// Make sure to free the memory.
free(struct1);
return 0;
}
A pointer is just an integer in reality, when you pass in struct1 to your function since struct1 is null you are just passing in a 0 to your function in reality. that value gets passed on the stack and you do a heap allocation and update the stack value with the new address. but when you return from the function, that value just gets popped of the stack and you have leaked that memory. the value of struct1 in main (which is also on the stack still keeps its value 0(NULL). so you have to pass in a pointer to your pointer if you want to update that value, or what might be easier is just to return the malloc'd pointer from your function.
This is one way you could modify your function to work:
#include <stdio.h>
#include <stdlib.h>
struct myStruct
{
int number;
};
struct myStruct*
allocateMem()
{
struct myStruct* struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
return struct1;
}
int
main(int argc, char *argv[])
{
struct myStruct *struct1 = allocateMem();
printf("number: %d\n", struct1->number);
return 0;
}
Because you are changing the struct1 pointer in the method, you need to either return the pointer to the caller, or pass it as a double pointer (address of the caller's pointer), e.g.
Return:
struct myStruct* allocateMem()
{
struct myStruct* struct1 = malloc(sizeof(struct myStruct));
struct1->number = 500;
printf("struct1->number: %d\n", struct1->number);
return struct1;
}
Double pointer:
void allocateMem(struct myStruct **struct1)
{
With the allocation and usage as per #Grijesh's comments below.