malloc of array in struct passed as argument - c

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()!

Related

Pointer to pointer to variable of struct in C

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.

how to index struct containing a pointer to pointer for struct which is malloc block

i am created a struct
typedef struct t{
int top;
int value;
}s;
and another structure
typedef struct y{
int top1;
s **p
}z;
z *p1;
created a block by malloc
p1 = (z*) malloc(sizeof(z));
p1->p = (s**) malloc(10 * sizeof(s));
I tried with indexing the s structured block by
p1->p[4]->top;
but i got error. is there a way to index pointer to pointer type in C
Address them with single pointer.
typedef struct y{
int top1;
s *p; //Single pointer only
}z;
z *p1;
p1 = malloc(sizeof(z)); //Don't cast...
p1->p = malloc(10 * sizeof(s));
//And then:
p1->p[4].top;
If you still want double pointers, then:
typedef struct y{
int top1;
s **p;
} z;
z *p1;
size_t i;
p1 = malloc(sizeof(z)); //Create z structure object
p1->p = malloc(10 * sizeof(*p1->p)); //Create array of pointers to objects
//Now fill that array with your objects
for (i = 0; i < 10; i++) {
p1->p[i] = malloc(sizeof(*p1->p[i]));
}
//Now access to property as:
p1->p[4]->top; //Do something.
The second option is less preferable but depends on you, because doing single mallocfor 10 objects in a row is more efficient than doing 10x times single object and 11th time for initializing base array of pointers.
In struct y{ ...; s **p }, member p represents a pointer to a pointer to structure s, and not a pointer to structure s.
So p1->p[4] is a pointer to an s, not an s itself, so you cannot access member top with accessor .. To get around the compiler error, you would have to use accessor ->, which dereferences the pointer value, but then you yield undefined behaviour at runtime, since the pointer value is not initialized.
To solve the problem, you could either change the data type of p to s *p (as suggested by #tilz0R), or you could adapt your code to actually deal with pointers to pointers:
typedef struct t{
int top;
int value;
}s;
typedef struct y{
int top1;
s **p;
}z;
z *p1;
int main() {
p1 = malloc(sizeof(z));
p1->p = malloc(10 * sizeof(s*));
for (int i=0; i<10; i++) {
p1->p[i] = malloc(sizeof(s));
}
p1->p[4]->top = 5;
}
Note that pointers to pointers are more complicated to handle, as you need an extra step/loop to initialize the pointers and to free them later on. So actually I'd prefer the s *p-way; But sometimes pointers to pointers are more appropriate, e.g. if particular slots of the array shall remain "empty"; then you could set the respective pointer to NULL, which would not be possible in an array of struct objects.

Write a Struct to Binary File in C [duplicate]

I am having problems with this program. It's very simply. I need to assign values to my struct from the pointers I created, but I keep getting a segmentation fault. Any ideas what I'm doing wrong:
#include <stdio.h>
#include <stdlib.h>
struct problem37
{
int a;
int b;
int c;
};
int main()
{
printf("Problem 37\n");
//create struct
struct problem37 myStruct;
//create the pointer
int* p;
int* q;
int* r;
*p = 1;
*q = 5;
*r = 8;
//read the data into the struct using the pointers
myStruct.a = *p;
myStruct.b = *q;
myStruct.c = *r;
printf("%d\n", myStruct.a);
printf("%d\n", myStruct.b);
printf("%d\n", myStruct.c);
return 0;
}
Your are assigning a value to *p, *q and *r, but they are not initialized: they're pointers pointing to random memory.
You need to initialize them, either assigning them a new value allocated in the heap (with malloc):
int *p = (int*) malloc( sizeof(int) );
*p = 1;
or making them point to an already existent value:
int x;
int *p = &x;
*p = 1; // it's like doing x=1
Your problem is that you write at random memory locations since you do not initialize your pointers nor allocate memory.
You could do the following:
int* p = malloc(sizeof(int));
int* q = malloc(sizeof(int));
int* r = malloc(sizeof(int));
Obviously you need to free them when you are done using them:
free(p);
free(q);
free(r);
You're not allocating memory to the pointer. Therefore when you're doing *p and *q and *r you're dereferencing a null pointer (or a random pointer). This leads to a segmentation fault. Use p = malloc(sizeof(int)); when you declare the variables.

Pointer having issue to struct in C programming

I am having a problem with pointers.
this is an example of what I want
struct Book
{
char name[10];
int price;
}
int main()
{
struct Book b[10]; //Array of structure variables
struct Book* p; //Pointer of Structure type
p = &b; --- HERE is the ERROR
}
This is the error part
p = &b;
b is an array, which can itself decay into a pointer variable. By writing &b, you actually take the address of that pointer and then you end up with pointer to a pointer. It is enough to just write p = b.
Try this. I have not checked but this should work.
p = b;
now if you want to iterate you array of structure then do this
// Example program
#include <stdio.h>
struct Book
{
char name[10];
int price;
};
int main()
{
struct Book b[10]; //Array of structure variables
struct Book* p; //Pointer of Structure type
p = b;
int i = 0;
for(i = 0 ; i<10; i++)
{
printf("Price : %d\n", (p+i)->price);
}
}
b itself is a pointer. Here you can think of arrays as of pointers. So use p=b instead of p=&b

Heap and Stack issues with Structs - C programming

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.

Resources