Malloc array of struct in C - c

Here is what I do:
I count the number of file inside a folder, get data from this file inside a array of struct.
I want to malloc this array of struct, since I do not know the exact number of file before strating the program.
Here is my code:
struct get_data{
int sequence;
int mask_ID;
char *name;
float intensity;
float angle_correction;
double points[10000];
float X_interval;
};
struct get_data all_data[number_of_file];
Consider I get number_of_file before somewhere in the program.
I want to know how to malloc the struct all_data. I search but got lost at some point. Any help would be welcomed. Thank you.
Mel.

I suggest you give a fixed length to the name variable inside the structure or else you would have to malloc that for each structure. The declaration could look like this:
struct get_data
{
int sequence;
int mask_ID;
char name[256];
float intensity;
float angle_correction;
double points[10000];
float X_interval;
};
Then, you may malloc an array of structures using the following code:
struct get_data *all_data;
all_data = malloc(number_of_files * sizeof(struct get_data));
if (all_data == NULL)
{
printf("Malloc failed!\n);
return -1;
}
/* now you can access each file structure using a for instruction */
int i;
for (i = 0; i < number_of_files; i++)
{
all_data[i].sequence = ...;
/* etc. */
}

Related

failing freeing dynamic struct array in c

I'm having some problem with freeing dynamic struct array and I can't understand why.
first of all there is this struct:
typedef struct
{
char name[LEN];
char address[MAX];
} Airport;
And the constructor I made for this struct isn't using allocation for this struct building.
sec of all there is this struct:
typedef struct
{
Airport* airports;
int maxAPS;
int currentAPS;
} AirportManager;
//constructor
void addAirport(AirportManager* pAirportManager)
{
if (pAirportManager->maxAPS == pAirportManager->currentAPS)
{
pAirportManager->maxAPS++;
pAirportManager->airports = (Airport*)realloc(pAirportManager->airports, sizeof(Airport)*pAirportManager->maxAPS);
//pAirportManager->airports[pAirportManager->currentAPS] = *(Airport*)malloc(sizeof(Airport));
}....
and when I'm ending my program and want to free the AirportManager with the following code:
void freeAirportManager(AirportManager* pAirportManager)
{
for (int i = 0; i < pAirportManager->currentAPS; i++)
free(&pAirportManager->airports[i]);
free(pAirportManager->airports);
}
I've debuged this one and all the parameters are just fine but after one run in the loop the program exits, what should I change in the free function ?
do I need the marked line in the constructor ? I just added this on thinking it might help, but seems to not work as well... do I need to free only the array itself ?
for (int i = 0; i < pAirportManager->currentAPS; i++)
free(&pAirportManager->airports[i]);
You need only to free pAirportManager->airports. You do not have pointer to pointer here.
So instead of those two lines:
free(pAirportManager->airports);
I would use flexible array member instead of pointer.
typedef struct
{
char name[LEN];
char address[MAX];
} Airport;
typedef struct
{
size_t maxAPS;
size_t currentAPS;
Airport airports[];
} AirportManager;
For sizes use size_t type instead of int

Sending Pointers of Structs to a Function in C

I don't love this, but I have a struct with nearly 45 members inside; all are characters or character arrays. That said, I am going to need to optimize the way I initialize each struct. Ordinarily, I would pass the entire object into my init_struct() function, but I feel like that is not the best way to do this.
How would I create and use a pointer to the struct to accomplish this?
Old Method would look something like this:
void init_struct(struct general){
...initialize members...
}
int main(){
struct general[10];
for(int i = 0 ; i < 10 ; ++i){
init_struct(general[i];
}
}
Since this struct is so large, as I said nearly 45 members inside it, I think a point to the struct would go a long way in optimizing this process. How would I accomplish that?
Just in case you need, here is the typedef for my struct
typedef struct
{
//Basically, everything we want to read from HUDL should be here...
int play_num;
char down;
char dist[3];
char ydln[4];
char gnls[3];
char hash[3];
char home[20];
char away[20];
char odk[2];
char qtr[2];
char series[3];
char result[20];
char penalty[20];
char act_cb[20]; //How do they act post-snap
char act_dl[20];
char act_lb[20];
char act_ol[20];
char act_qb[20];
char act_rb[20];
char act_saf[20];
char aln_cb[20]; //How do they align pre-snap
char aln_dl[20];
char aln_lb[20];
char aln_ol[20];
char aln_qb[20];
char aln_rb[20];
char aln_saf[20];
char aln_wr[20];
char blitz[20];
char box_cnt[3];
char saf_count[20];
char coverage[20];
char cvr_basic[20];
char def_front[20];
char mtn_def[20];
char num_rush[3];
char off_form[20];
char form_var[20];
char motion[20];
char off_pro[20];
char off_play[20];
char play_var[20];
char personnel[20];
char play_type[20];
char time[2];
char score_diff[4];
char field_zone[2];
char dd_type[2];
char form_strength[2];
} HUDL; // MAXIMUM of 63 Members
There's a couple of things wrong on your code.
First of, your function definition is wrong because you omit the parameter name. Your function definition should look like this:
void init_struct(struct general mygeneralstruct){}
Alternatively, you could use an alias for your struct using typedef, like so:
typedef struct {
int a;
} general;
In which case, your function declaration could look like this:
void init_struct(general mygeneralstruct){}
You have the same problem when you declare your array of structures. You omit the name of your variable. Instead of
struct general[10];
it should be
struct general mygeneralstruct[10]
or
general mygeneralstruct[10](typedef)
Finally, you can't change your array of structures by passing each structure's value to the function. You need to pass each structure's address instead.
Your function declaration should then be(using typedef):
void init_struct(general* mygeneralstruct){}
and the code in the loop:
init_struct(&mygeneralstruct[i]);
To pass a pointer to your array element, you just prefix the parameter with &, make sure you declare the function correctly:
void init_struct(HUDL* pGeneral){
if ( pGeneral != NULL ) {
//This will ensure the entire structure contains '0'
memset(pGeneral, 0, sizeof(HUDL));
...initialize members...
}
}
int main(){
HUDL general[10];
for( int i=0; i<(sizeof(general) / sizeof(general[0])); i++ ) {
init_struct(&general[i]);
}
}
I'm not sure why you haven't used the typedef 'HUDL' makes life a lost easier and code easier to read.
A slightly cleaner and better approach would be to have a constructor and destructor function to allocate memory dynamically to structure and free it after use.
static void HUDL_destroy(HUDL* ptr)
{
if(ptr)
{
//...any other clean up that needs to be done goes here..
free(ptr);
}
}
static HUDL* HUDL_create()
{
HUDL* ptr = malloc(sizeof(HUDL));
if(!ptr)
return NULL;
//do initialization bits...
init_struct(ptr);
return ptr;
}
int main()
{
//allocate and initialise structure
HUDL *general = HUDL_create();
//do stuff...
//free structure after use
HUDL_destroy(general);
}
You might need an array of pointers in your case. So modify your main() accordingly.
int main()
{
//we need an array of structure pointers
HUDL* general[SIZE];
//allocate and initialize structure
for(int i=0; i<SIZE; i++)
general[i] = HUDL_create();
//do stuff...
//free structure after use
for(i=0; i<SIZE; i++)
HUDL_destroy( general[i] );
}

How do I return a struct (from a function) containing an array with the correct elements in that array?

I'm making a program that returns a struct containing an array, but the elements in the array are completely wrong. I keep searching for an answer on this site, Google, and even Bing and nothing. The best I can find are answers like this:
Functions can't return arrays in C.
However, they can return structs. And structs can contain arrays...
from How to make an array return type from C function?
Now, how do I fix this without the use of pointers?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
struct Codes{
int as;
int a[];
};
struct Codes create(int as){
int a[as];
for(int j = 0;j<as;j++)
a[j]=j+1;
struct Codes c;
c.as = as;
c.a[c.as];
for(int i=0; i<as; i++)
c.a[i] = a[i];
for(int i=0; i<as; i+=1)
printf("%d \n", c.a[i]);
return c;
}
int main(int argc, char **argv) {
struct Codes cd;
int as = 4;
cd = create(as);
for(int i=0; i<4; i+=1)
printf("%d \n", cd.a[i]);
}
Actual output:
1
2
3
4
0
0
2
-13120
Expected output:
1
2
3
4
1
2
3
4
structs with flexible value are not meant to be manipulated by value, only by pointer.
You cannot return a struct with a flexible member by value, because C does not know how many items it needs to allocate to the return value, and how many bytes it needs to copy.
Allocate your struct in dynamic memory using malloc of sufficient size, copy your data into it, and return a pointer to the caller:
struct Codes *c = malloc(sizeof(struct Codes)+as*sizeof(int));
c->as = as;
for (int i = 0 ; i != as ; i++) {
c->a[i] = i+1;
}
return c;
Change your function to return a pointer; make sure the caller frees the result.
In your function, struct Codes create(int as), the struct Codes c; is allocated on the stuck, so the memory is no longer valid once the function returns...
...It is true that the core struct is copied in the return value... but the variable array length c.a isn't part of the struct (it's a memory "trailer" or "footer") and isn't copied along with the return value.
Either:
allocate the struct and pass it to a struct Codes create(struct Codes *dest, int as) function; OR
make the struct array fixed in size struct Codes{ int as; int a[4]; };
Good luck.

accessing the array inside array of structures

I have a structure as follows
struct a
{
char* ap;
char* inputs[10];
int e;
};
then I have created an array of this structure like struct a list [100];
now i want to fille the array inputs[10] and for that I am using the syntax to access the first location :
ip=0;
inp=0;
list[ip].inputs[inp]
but I am gettin the error "error C2107: illegal index, indirection not allowed" on compiling the code
please suggest how to access the array location inside array of structure.
regards
priya
Here you use array of character pointer in your structure. So Initially you allocate memory for you structure by creation list of 100. I think you didn't create memory for you array of character pointer. You have to create memory for each of character pointer. So I suggest example code.
#include <stdio.h>
struct a
{
char* ap;
char* inputs[10];
int e;
};
int main()
{
int ip=0;
int inp=0;
struct a list[100];
list[ip].inputs[inp]= (char*)malloc(25);
scanf("%s",list[ip].inputs[inp]);//Or other copy function to fill string
printf("output %s",list[ip].inputs[inp]);
}
Working fine on my pc.. here is my code..
#include <stdio.h>
struct a
{
char* ap;
char* inputs[10];
int e;
};
int main()
{
int ip=0;
int inp=0;
struct a list[100];
list[ip].inputs[inp] = 'A';
printf("This: %c", list[ip].inputs[ip]);
return 0;
}
OUTPUT= This: A
let me know whether it helped or not..
The struct themselves do not have data. You need to create objects of the struct type and set the objects ...
struct a
{
char* ap;
char* inputs[10];
int e;
};
/* I like to separate the type definition from the object creation */
struct a list [3];
list [0].inputs[0] = "Choclate";
list [0].inputs[1] = "Almond";
list [0].inputs[2] = "Rasberry";
Hope it ll usefull. Also refer this article

dynamically expanding array of struct

I am (trying to) write a server-side daemon in c, and it accepts connections from clients. I need a struct that keeps information on each open connection, so I have created an array of my defined struct, and I have it dynamically re-sizing with realloc.
The problem I have is creating the struct within the array. I keep getting this error:
test.c:41: error: conversion to non-scalar type requested
What am I doing wrong?
I spend most of my time in PHP, and am a noob with c. I realize that I am making some simple, beginner mistakes (in other words, feel free to make fun of me). If I am doing something stupid, please let me know. I've put my quality time in with google, but have not figured it out. I have reproduced the issue on smaller scale, as below:
here is my test.h:
typedef struct test_ test;
and here is my test.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "test.h"
//define the struct
struct test_ {
int id;
char *ip;
int user;
char *str;
};
//yes, the list needs to be global
test *test_list;
//
// add an item to the global list
//
int add(int id, char *ip, int size)
{
//
// increment size
if(id>size) {
size = id;
//try to expand the list
test *tmp = realloc(test_list,size);
if(tmp) {
//it worked; copy list back
test_list = tmp;
} else {
//out of memory
printf("could now expand list\n");
exit(1);
}
}
//
// HERE IS THE TROUBLE CODE::
test_list[id] = (struct test)malloc(sizeof(test)+(sizeof(int)*5)+strlen(ip)+1);
test_list[id].id = id;
test_list[id].ip = malloc(strlen(ip));
strcpy(test_list[id].ip,ip);
test_list[id].user = 0;
test_list[id].str = NULL;
}
//
// main
//
int main(void)
{
//initialize
int size = 1;
test_list = malloc(size*sizeof(test));
//add 10 dummy items
int i;
for(i=0; i<10; i++) {
size = add(i, "sample-ip-addr", size);
}
//that's it!
return 0;
}
Try changing
test *tmp = realloc(test_list,size);
to
test *tmp = realloc(test_list,size*sizeof(test));
then delete
test_list[id] = (struct test)malloc(sizeof(test)+(sizeof(int)*5)+strlen(ip)+1);
When you allocate for test_list, there's already space for each member of the struct allocated, so you don't need to do it again. You just have to allocate for any pointers within the struct
The return value from 'malloc' is the memory address you've allocated. You can't cast it to a struct. What would that even mean?
You want something like: test_list=realloc(test_list, num_alloc * sizeof(test_));

Resources