Memory Pointers and Arrays - c

I have this struct:
struct table{
int miny,maxy,maxa;
int** list;
};
and its subsequent typedef:
typedef struct table *StatTable;
So, my doubt is the following:
On the initialisation of a struct table I do this and it might work fine:
StatTable newStatistic(int min,int max,int maxauts){
StatTable aux=malloc(sizeof(StatTable));
aux->miny=min;
aux->maxy=max;
aux->maxa=maxauts;
aux->list=calloc(((max-min))*(maxauts+1),sizeof(int));
return aux;
}
Since I declared that list as an int ** can I implement a function this way?
int get(StatTable st,int ano,int nAut){
return st->list[ano-getMinYear(st)][nAut];
}

StatTable aux=malloc(sizeof(StatTable));
This statement will not create an variable of struct table. StatTable is a typedef for a pointer to the struct variable so sizeof(StatTable) gives size of a pointer so this statement wont allocate space for a variable of structure.
Therefore
aux->miny=min;
aux->maxy=max;
aux->maxa=maxauts
these statements results in segmentation fault since memory is not allocated for them.
To create a variable and then to make aux a pointer to it use,
StatTable aux=malloc(sizeof(struct table));

This:
StatTable aux=malloc(sizeof(StatTable));
...is wrong. You're allocating the size of a pointer to aux. You should allocate the size of the structure instead:
StatTable aux=malloc(sizeof(struct table));
Instead allocating one contiguous block of memory like this:
aux->list=calloc(((max-min))*(maxauts+1),sizeof(int));
...you should allocate your 2D pointers like this:
aux->list = calloc(max - min, sizeof(*aux->list));
for (int i=0; i<max-min; i++)
aux->list[i] = calloc(maxauts + 1, sizeof(**aux->list));

Related

Pointer as a structure variable in c

When I use code like this :
typedef struct {
int x;
int *pInt;
} tData;
tData *ptData = malloc(sizeof(tData));
If i understand it right, i allocated memory with size of tData and returned adress to this allocated memory to pointer *ptData.
But what if i used this code :
typedef struct {
int x;
int *pInt;
} *tData;
If I want to allocate memory to this struct, do I need a struct name? Because for me, if I allocate like malloc(sizeof(*tData));, it seems to me like I am allocating memory only for the pointer, not for the structure itself. When I want to refer to data in this structure, do I need to use pointer to pointer to a struct?
It confuses me a bit and I couldn't find the answer I am looking for.
Thank you for any explanation!
This is one of the reason one should avoid creating type-aliases of pointers.
As for how to use it, instead of passing the type to the sizeof operator, use the variable. Like e.g.
typedef struct {
int x;
int *pInt;
} *tData;
tData ptData = malloc(sizeof *ptData); // Allocate memory for one structure

Access values of structs from a pointer in a struct

I'm going to try and keep this as brief as possible.
So I have two structs:
typedef struct someStruct named;
struct someStruct {
void *key;
void *value;
};
typedef struct anotherStruct namedToo;
struct anotherStruct {
named **table;
unsigned int size;
};
Okay great, now ingore any possible mistakes above, this is uneditable code.
Now I have two methods:
namedToo *init(float ignoreThis) {
namedToo *temp;
temp = malloc(sizeof(namedToo)); //some memory for the second struct
temp->table = malloc(sizeof(named)*100); //lets say this 100 is for 100 buckets/cells/named elements
return temp;
Method 2:
int insert(namedToo *temp, void* key, void* value) {
temp->table[0]->key = key; //My problem, I need to access the value and key inside named from the pointer inside namedToo. How can I do this?
}
The comment has my problem :
My problem, I need to access the value and key inside named from the pointer inside namedToo. How can I do this? I would need to change and grab value/key on their own from time to time.
The declaration named **table; says table is pointer to a pointer to named, or alternately an array of pointer to named. The latter is you seem to intend.
This allocation:
temp->table = malloc(sizeof(named)*100);
Allocates space for 100 named, but what you need are 100 named *, and each of those must point to a named. Given the definition of named this is likely enough space, however at this point you have an array of uninitialized pointers. Attempting to access them results in undefined behavior, which in this case manifests as a core dump.
You need to allocate space for an array of pointers, then initialize each of those to a single dynamically allocated instance of named. So you should be allocating space like this:
int i;
temp->table = malloc(sizeof(named *)*100);
for (i=0; i<100; i++) {
temp->table[i] = malloc(sizeof(named));
}
Then your insert method should work properly.

Struct with multiple arrays which size is defined in execution time

What I would like to have, is a struct like this:
struct Store{
int client_debts[];
struct items[];
};
When the execution begins, the program read an input file that defines the size of the arrays in that struct, so i could do something like this:
struct Store s;
int client_debts[defined_size];
s.client_debts = client_debts;
How can I achieve that?
PD: I tried using pointers in the struct and then assigning them the arrays, but when the function that created the arrays ended, the array memory is liberated so the pointer keeps pointing to a unassigned memory thus creating segmentation faults.
The usual way to do what you want is to allocate them dynamically:
struct Store{
int *client_debts;
struct mystruct *items;
};
struct Store store;
int n;
scanf ("%d", &n);
if (n <= 0)
error_message();
store.client_debts = malloc (sizeof (*store.client_debts) * n);
store.items = malloc (sizeof (*store.items) * n);
if (!store.client_debts || !store.items)
error_message();
Even though they are pointers, they will act exactly like the arrays of your original declaration.

opaque c struct containing dynamic arrays

Is this the correct way to allocate memory for a c struct that contains a dynamic array? In particular, is the way I allocate memory for myStruct correct, considering that it is not yet known how big the struct actually is?
//test.h
struct Test;
struct Test * testCreate();
void testDestroy(struct Test *);
void testSet(struct Test *, int);
//test.c
#include <stdlib.h>
struct Test{
double *var;
};
struct Test * testCreate(int size){
struct Test *myTest = (struct Test *) malloc(sizeof(struct Test));
myTest->var = malloc(sizeof(double)*size);
return(myTest);
}
void testDestroy(struct Test * myTest){
free(myTest->var);
free(myTest);
}
void testSet(struct Test * myTest, int size){
int i;
for (i=0;i<size;++i){
myTest->var[i] = i;
}
}
structs have fixed size, and that's what sizeof returns.
Your struct has on element, a double pointer, and that has a (platform dependent) fixed size.
Your testCreate function does things correctly. In case you don't know the size of the dynamically allocated part, you can set the pointer to NULL to denote that the memory has to be allocated later.
Yes, you correctly malloc space for the struct and then space for the array of doubles in the struct. As a practical matter, you should always test the return from malloc() for NULL before attempting to use the memory. Also, most programs like this store the size of the array in the struct as well so you can write more general code that ensures it doesn't run off the end of the allocated space.

Struct to bidimensional struct pointer assignment in C

I want to get work this code and I googled and asked in efnet and freenode but I didn't find the answer.
What I want is to assign a struct woot to an another bidimensional struct woot *, and I need malloc to do that.
Then, how can I use malloc there and how to assign the struct? Thanks.
#include <stdio.h>
struct omg {
int foo;
};
struct woot {
struct omg *localfoo;
int foo;
};
int a = sizeof(struct woot);
int main(void){
struct woot *what[10][10] = (struct woot *) malloc(100*a);
struct omg hahaha[100];
hahaha[1].foo = 15;
what[1][6].localfoo = &hahaha[1];
}
struct woot *what[10][10] = (struct woot *) malloc(100*a);
I'm curious, does this code even compile? (edit: no, it doesn't.) In any case:
You don't really need malloc() here, declaring struct woot *what[10][10]; should be enough.
Typecasting the returned void* pointer when calling malloc() is unneeded in C (and considered as bad form).
(Not really an answer, I know... I would post it as a simple comment but I don't have enough points yet.)
edit: Oops, others have pointed out the same while I was writing this post.
new edit: Here is a better version of your code, with some mistakes corrected:
#include <stdio.h>
#include <stdlib.h> // needed for malloc()
struct omg {
int foo;
};
struct woot {
struct omg *localfoo;
int foo;
};
int main(void){
const int a = sizeof(struct woot); /* there is no reason "a" should be global...
actually, "a" is not needed at all, and, even if it
were needed, it should be declared as "const" :) */
struct woot *what[10][10];
struct omg hahaha[100];
hahaha[1].foo = 15;
what[1][6]->localfoo = &hahaha[1];
what[7][2] = malloc(a); // I would write "malloc(sizeof(struct woot))"
return 0; // main() should return an int, as declared!
}
You're trying to initialize an array with a scalar value (the pointer returned by malloc). If you really want a 10 by 10 matrix of pointers to structs (and not a 10 by 10 matrix of structs), you don't need malloc:
//Statically allocated 10x10 matrix of pointers, no need for malloc.
struct woot *what[10][10];
To assign a pointer to a cell in that matrix:
struct woot oneSpecificWoot;
what[1][2] = &oneSpecificWoot;
If this is really, really what you want, you could then create a bunch of woots dynamically an populate it. Something like this:
int i, j;
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
what[i][j] = malloc(sizeof(struct woot));
//Of course, you should always test the return value of malloc to make sure
// it's not NULL.
}
}
But if you're going to do that, you might as well just statically allocate the woots themselves:
//A 10x10 matrix of woots, no malloc required.
struct woot what[10][10];
The first case (a 2-D array of pointers) would be more likely if the woots are being created somewhere else, and you just want references to them in a grid lay out, or possibly if you don't know the dimensions of the grid at compile time. But in your code, you're using malloc to create a fixed number of them, so you might as well just have the compiler allocate them statically.

Resources