Initializing size of struct array after declaration in C? - c

I've done some searching around, but nothing I've found has answered my question specifically regarding structs:
In my program I have two structures: one contains data, the other contains an array of the first structure (used to make returning struct arrays easier).
I do not know the size of the aforementioned structure array until running a few lines of code. From what I've found there isn't a way to define the size of an array (or any type) after it has already been declared, although I would like to know if this holds true for structs.
If not, is there way to define the size of a previously declared array within a struct without using malloc? Using malloc with struct arrays seems a bit complicated and I haven't been able to wrap my head around it.
typedef struct
{
char **data;
} struct1;
typedef struct
{
struct1 data[];
} struct2;
int main(int argc, char **argv)
{
//Pretend there is code here that finds the size I need
size = 5;
struct2 Info;
Info.data = new struct1[size]; //Clearly this won't work, but does C offer anything comparable?
return 0;
}

Related

Struct within struct, using typedef and arrays

UPDATE: Code is correct and sensible, comments provide how to assign values to struct variables
I am writing a struct in C that contains 2 integer arrays and an array of custom-defined type 'info'. This 'info' type just contains several int variables. Here is the piece of code that I've come up with having done a bit of searching around the web:
typedef struct info {
int test_count;
int skip_count;
int prime_count;
} info;
struct myStruct {
int arr1[10];
int arr2[20];
info info[20];
};
This does not generate any compiler warnings or errors, but is it the most sensible implementation given what I'm trying to do?
Also– How would I assign values to the info variables and then access them through myStruct? I've tried various statements using the dot operator, but I cannot get them past the compiler.
Looks OK to me. Example usage struct myStruct x; x.info[3].skip_count = 4;
– M.M
And given: struct myStruct x; you should be able to use x.info[13].prime_count to access an element of that array.
– Jonathan Leffler

How to program these structures?

I have three objects, which (at the moment) I am representing as structs:
a Dataset
a DatasetWindow
a MovingWindow
and a variable windowSize
There may be multiple Dataset's and each should have it's own DatasetWindow.
Ok, fair enough, to me that sounds like I make a DatasetWindow struct and put it as a member of a Dataset struct
There would be just one MovingWindow, but it should know about all the Dataset's.
Ok, so far it seems pretty simple. I create another struct for MovingWindow and it has a pointer to Dataset. (an array of datasets).
So so far, I have something like this:
typedef struct {
int *buffer;
int someOtherMember;
} DatasetWindow;
typedef struct {
int someMember;
DatasetWindow *window; //Pointer to a DatasetWindow obj.
} Dataset;
typedef struct {
int offset;
int someMember;
Dataset *datasets; //Array of Dataset
} MovingWindow;
The part I am having trouble with is this:
MovingWindow should know windowSize, as should each DatasetWindow.
But Dataset should preferably not need to know what windowSize is.
I don't know how to arrange my structures to support this?
You can modify the definitions of structs MovingWindow and DatasetWindow to incorporate a member (pointer or a interger variable) holding the value of your windowSize.

how to scanf a global variable outside the main?

I have a problem ,how to make an array vertextDegree [nbColours] with nbColours elements in it ,but the "nbColours" unknown and I have to get it get it from a file .
look at the code
so what can I do to solve this problem ?
int nbEdges,nbVetices, nbColours ;
typedef struct st_graphVertex
{
int index;
int colour;
int val ;
int vertexDegree[nbColours]; // it won't work because nbColours unknown
// here and I want get it from file in the main
struct st_graphVertex *next;
t_edgeList *out;
}t_grapheVertex;
In C99 there is a special syntax for this, although it is limited to only one array per struct (which is OK in your case) - put the array as the last member, and drop its size, like this:
typedef struct st_graphVertex
{
int index;
int colour;
int val ;
struct st_graphVertex *next;
t_edgeList *out;
int vertexDegree[];
}t_grapheVertex;
Now the size of your array is flexible: you can decide what it should be at runtime. Moreover, different st_graphVertex values can have this size set differently (although in such cases it's typical to put nbColours with the specific size as a field in the same struct).
The "payment" for using this trick is inability to allocate such structs on the stack or in the global or static memory. You must allocate them dynamically, like this:
t_grapheVertex *vertex = malloc(sizeof(t_grapheVertex)+sizeof(int)*nbColours);
You can't do that in pre-C99 or in non-last members. Instead, you can make that member a fixed-size pointer:
int* vertexDegree;
And make it point to an array of appropriate size known at runtime:
myVertex.vertexDegree = malloc(nbColours*sizeof(int));
You can also do it using Struct Hack, which is however similar to what dasblinkenlight told in his answer.

Is it possible to create a struct whose size is not known at compile time?

As the question states I am looking to create a struct in C whose total size I do not know at compile time.
For example, I would like to create a struct that contains a count value and an array with count elements. I know this could be implemented as:
typedef struct myStruct{
int count;
int *myArray;
} myStruct;
However, I want this struct to take up one solid block of memory so I could use memcpy() on it at a later point in time. Like this:
typedef struct myStruct{
int count;
int myArray[count];
} myStruct;
It sounds like you're looking for flexible array members:
typedef struct myStruct
{
int count;
int myArray[];
} myStruct;
Then, when you allocate it later:
myStruct *x = malloc(sizeof(myStruct) + n * sizeof(int));
x->count = n;
Yes, you can. If you use C99, there's flexible array members. Otherwise, you can do what Microsoft does. Take your original structure definition and map it to an existing block of memory. Reassign the pointer to point just after the structure definition.
Also, the MS approach would allow multiple members with variable size; you just need to properly update each pointer.
(Note: The "MS approach" is just something encountered often in Windows APIs; I don't know if there's an actual term for the practice.)

a way to copy a 2dimensional array into a struct array

I have this array filled up with characters in my maze.c file:
char normalMazeArray[6][12]; dynamically filled as mazeArray[row][column]
Now I want to pass what the array to the mazeArray that is located in my struct (maze.h)
my struct is called:
typedef struct {
char mazeArray;
} maze_t;
I have tried copying it as follows:
maze_t* maze;
char normalMazeArray[6][12]; // filled with info
typedef struct {
char mazeArray;
} maze_t;
maze->mazeArray = normalMazeArray;
however it is not working,
anyone who could help me?
The thing what you're trying to do is not exactly possible. There are two slightly different solutions you can use, though.
normalMazeArray is of type char [6][12] - it's an array. You can either copy its contents to the same type of array using memcpy():
typedef struct {
char mazeArray[6][12];
} maze_t;
memcpy(maze->mazeArray, normalMazeArray, sizeof(normalMazeArray));
or if your normalMazeArray persists throughout the lifetime of the program, you can assign a pointer to it in the structure:
typedef struct {
char (*mazeArray)[12];
} maze_t;
maze->mazeArray = normalMazeArray;
Wait, how??
First of all, maze is a pointer, so you can't have maze.mazeArray. Second of all, maze->mazeArray is of type char, while mazeArray is of type char**. No can do.
You should write a function which allocates char** array, and then strdups strings from mazeArray. Or, if you want ownership transfer, and not just copy, you could go like this:
typedef struct {
char** mazeArray;
} maze_t;
maze_t maze;
maze.mazeArray = mazeArray;

Resources