I have a structure like this below and I would like to allocate the members of structA inside the void function as shown below. Basically want to allocate the structure size over the void function using pointer and then use this structure pointer in other functions to access the fields. Below is an example of how I would like to write the code, but not clear of pointer and structure usage. In the print function header, do I use a struct pointer or just the struct itself?
typedef struct A {
int *x;
int *y;
} A;
void allocateStruct(int sizeN, A *aType);
void printInfo(A aType);
int main() {
A genericA;
allocateStruct(5, genericA);
int x[5] = {2, 3, 4, 5, 6};
int y[5] = {12, 36, 40, 52, 23};
genericA.x = x;
genericA.y = y;
printInfo(genericA);
}
void allocateStruct(int sizeN, A* aType) {
aType.x = (int)malloc(sizeN * sizeof(int));
aType.y = (int)malloc(sizeN * sizeof(int));
}
void printInfo(A genericP) {
......
}
If I compile your code
#include <stdlib.h>
typedef struct A {
int *x;
int *y;
} A;
void allocateStruct(int sizeN, A *aType);
void printInfo(A aType);
int main() {
A genericA;
allocateStruct(5, genericA);
int x[5] = {2, 3, 4, 5, 6};
int y[5] = {12, 36, 40, 52, 23};
genericA.x = x;
genericA.y = y;
printInfo(genericA);
}
void allocateStruct(int sizeN, A* aType) {
aType.x = (int)malloc(sizeN * sizeof(int));
aType.y = (int)malloc(sizeN * sizeof(int));
}
void printInfo(A genericP) {
/* */
}
I get
main.c: In function 'main':
main.c:13:23: error: incompatible type for argument 2 of 'allocateStruct'
allocateStruct(5, genericA);
^~~~~~~~
So I adapt the call to actually give the pointer the prototype is asking for.
#include <stdlib.h>
typedef struct A {
int *x;
int *y;
} A;
void allocateStruct(int sizeN, A *aType);
void printInfo(A aType);
int main() {
A genericA;
allocateStruct(5, &genericA);
int x[5] = {2, 3, 4, 5, 6};
int y[5] = {12, 36, 40, 52, 23};
genericA.x = x;
genericA.y = y;
printInfo(genericA);
}
void allocateStruct(int sizeN, A* aType) {
aType.x = (int)malloc(sizeN * sizeof(int));
aType.y = (int)malloc(sizeN * sizeof(int));
}
void printInfo(A genericP) {
/* */
}
And I get:
main.c: In function 'allocateStruct':
main.c:23:10: error: 'aType' is a pointer; did you mean to use '->'?
aType.x = (int)malloc(sizeN * sizeof(int));
^
So I do exactly that:
#include <stdlib.h>
typedef struct A {
int *x;
int *y;
} A;
void allocateStruct(int sizeN, A *aType);
void printInfo(A aType);
int main() {
A genericA;
allocateStruct(5, &genericA);
int x[5] = {2, 3, 4, 5, 6};
int y[5] = {12, 36, 40, 52, 23};
genericA.x = x;
genericA.y = y;
printInfo(genericA);
}
void allocateStruct(int sizeN, A* aType) {
aType->x = (int)malloc(sizeN * sizeof(int));
aType->y = (int)malloc(sizeN * sizeof(int));
}
void printInfo(A genericP) {
/* */
}
And I get:
main.c: In function 'allocateStruct':
main.c:23:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
aType->x = (int)malloc(sizeN * sizeof(int));
^
So I do as generally recommended for C and NOT cast malloc:
#include <stdlib.h>
typedef struct A {
int *x;
int *y;
} A;
void allocateStruct(int sizeN, A *aType);
void printInfo(A aType);
int main() {
A genericA;
allocateStruct(5, &genericA);
int x[5] = {2, 3, 4, 5, 6};
int y[5] = {12, 36, 40, 52, 23};
genericA.x = x;
genericA.y = y;
printInfo(genericA);
}
void allocateStruct(int sizeN, A* aType) {
aType->x = malloc(sizeN * sizeof(int));
aType->y = malloc(sizeN * sizeof(int));
}
void printInfo(A genericP) {
/* */
}
Result: No errors, no warnings.
Now test, using the given prototype for the print function and first implementation I can think of:
#include <stdlib.h>
#include <stdio.h>
typedef struct A {
int *x;
int *y;
} A;
void allocateStruct(int sizeN, A *aType);
void printInfo(A aType);
int main() {
A genericA;
allocateStruct(5, &genericA);
int x[5] = {2, 3, 4, 5, 6};
int y[5] = {12, 36, 40, 52, 23};
genericA.x = x;
genericA.y = y;
printInfo(genericA);
}
void allocateStruct(int sizeN, A* aType) {
aType->x = malloc(sizeN * sizeof(int));
aType->y = malloc(sizeN * sizeof(int));
}
void printInfo(A genericP) {
printf("%i %i\n", genericP.x[0], genericP.y[0] );
}
And I get the satisfying output:
2 12
Or the same output with the alternative you mention:
void printInfo2(A* genericP) {
printf("%i %i\n", genericP->x[0], genericP->y[0] );
}
Called as printInfo2(&genericA);
.
Admittedly, as yano rightly points out, this is a little too straightforward. It overwrites, from main, the allocated pointers, which represents a memory leak.
I have to guess at the purpose, but I go with yanos assumption that actually some copying of values (instead of pointers) makes most sense.
As an example for a single value (leaving most of the allocated memory uninitialised, if you do not fill in the /* more */
), do in main()
:
genericA.x[0] = x[0];
genericA.y[0] = y[0];
/* more */
Again with the same output.