Assign value to 2d array of struct in C - arrays

I want to create the game 2048 in C, I have a few structs to achieve this:
typedef struct Board {
unsigned int size;
Cell ***cells;
} Board;
typedef struct Cell{
unsigned int value;
} Cell;
The structs are given as a homework, so I cannot change them
What I want to do now is initialize the Board and put one value into it:
Board* create_board(const unsigned int size){
Cell ***cell = (Cell***)malloc(sizeof(Cell *) * size * size);
Board *myboard = {size, cell};
Cell c1 = {2048};
myboard.cells[0][0] = c1; //I need help in this line
return myboard;
}
I am just learning C and pointers are still a little confusing for me, especially if there are 3 * in a row. How do I go about assigning values to a triple pointer array inside a struct?
Any help is appreciated, it was very hard for me to find information online about this kind of problem.

Related

How to properly declare/initialize/finalize dynamic array of structs with other dynamic arrays

So what i want to achieve is global variable which represents pointer to dynamic array of structs which has other pointers to dynamic arrays inside.
So i've declared everything in the header file like that:
/*** "GLOB.h" ***/
//Dynamic Array of fixed Arrays of 4 floats each
typedef float DArray1[][4];
//Dynamic Array of Integers
typedef int DArray2[];
//Struct
struct MyStruct
{
//pointer to DArray1
DArray1 * A1;
//pointer to DArray2
DArray2 * A2;
//Length of A1 and A2
int len = 1;
//Some other simple elements of fixed size
};
//Dynamic Array of Structs
typedef MyStruct DAStructs[];
namespace GLOB
{
//pointer to DAStructs
extern DAStructs * SS;
//Few other simple variables initialized in place
};
Because i don't rly sure if i declared everything properly - first question is: how to declare such data-structure in C/C++?
And second(+third) is: how to properly initialize and finalize it with some variable length?
I guess initialization and finalization should be something like that:
#include "GLOB.h"
namespace GLOB
{
void Init_SS(int len) {
SS = new MyStruct*[len];
for(int k=0; k<len; k++){
SS[k].A1 = new float*[1][4];
for(int j=0; j<4; j++) SS[k].A1[0][j] = 0.0;
SS[k].A2 = new int*[1];
SS[k].A2[0] = 0;
}
}
void Fin_SS() {
int len = length(SS);
for(int k=0; k<len; k++){
delete [] SS[k].A1;
delete [] SS[k].A2;
}
delete [] SS;
}
}
But obviously it's just a mess of nonsense and not the appropriate code...
P.S. i'd rather avoid using or any other solutions cuz i want to learn first of all and second i need as much control over how elements will be placed in memory as possible cuz later i'll need to pass pointer to such structure to other functions imported from DLLs...
Well nobody answered, but actually the answer was really simple, cuz i did everything almost properly =)
My first (and main) mistake was that i forgot that arrays in C are just pointers to first elements, so instead of
typedef float DArray1[][4];
typedef int DArray2[];
typedef MyStruct DAStructs[];
it should be
typedef float (*DArray1)[4];
typedef int * DArray2;
typedef MyStruct * DAStructs;
And it's not needed to make pointer to array, cuz array is already pointer lol
And my second mistake was that i forgot (well it's not like i knew it =) that length of array in C not stored anywhere, so instead of length(SS) it should be another variable where length should be stored manually upon allocation.
But the whole logic which i assumed seem to be legit, and it works fine. Even tho i didn't tested my project for memory leaks, when i use finalization procedure it seem to free allocated memory without any problems...

How to dynamically allocate a struct containing multiple arrays?

I'm trying to make a struct that contains another struct with multiple arrays. I need to dynamically allocate those arrays too, so I think I need another pointer still.
int arraysize;
typedef struct Array{
int *size = arraysize;
unsigned int val[*size];
unsigned int x[*size];
unsigned int y[*size];
} Array;
typedef struct Image{
int height;
int width;
int max;
Array *data;
} Image;
OK, so once I finally figure that out, I still need to figure out how to dynamically allocate that memory using malloc. I'm totally lost there too. Any help at all would be greatly appreciated.
EDIT: more clarification:
I'm using the arrays to store three pieces of information that are all connected. Think of a chessboard, you could say knight E4, which tells you that on the 4th column of row E, there is a knight. If you started this process at A1 and ended at K10 you'd have a full chessboard right? The image struct is analogous to the chessboard, the Array is analogous to a list of a bunch of squares that compose the chessboard and the contents of those squares. (E.g. A1 null A2 knight a3 bishop etc...) Unfortunately, I don't know what kind of board will be passed through, it might be a 3x7 board or a 9x2 board etc. So I need to dynamically allocate the memory for those possibilities. Once I have the memory allocated I need to store information about the location and the contents of all of the "squares." Then I need to let a program pass through the height of the board, width of the board and the list of contents and I'd be done the hard part.
What you actually meant was:
typedef struct data {
unsigned int x;
unsigned int y;
unsigned int val;
} Data;
typedef struct image {
int height;
int width;
int max;
Data* data;
} Image;
and somewhere:
Image i;
i.height = 10;
i.width = 20;
i.data = malloc(sizeof(Data) * i.width * i.height);
...
// one of the ways how to access Data at 2nd row, 3rd column:
*(i.data + i.width * 1 + 2).val = 7;
...
free(i.data);
i.data = NULL;
But what you actually need is some good book ;)

Is there a better way to store pairs of ints?

I'm sorry if this is very basic but I'm still learning all that things I can do in C and can't figure out how to do this.
I create pairs of ints in a program and then need to store them. The way I have been doing it so far is by creating a struct:
struct list_el {
short *val; //first value
short *val2; //second value
struct list_el * next;
};
typedef struct list_el item;
I can iterate though the list fine in my normal program but I want to send this to Cuda and am not sure how to transfer the whole struct into Cuda(I know I can make a reference to it). I'm wondering if there's another way I can structure this data so maybe its array? The format I need is in is just simple pairs (something like this 10:5, 20:40, etc..). I thought worst case I can use a char string and have the pairs as characters and then parse them once the main array is in Cuda but I'm wondering if there's a better way create this list of list?
Assuming that you can use two separate arrays, and thinking about how to use/read/write them in CUDA, I will arrange the data in two arrays mainly due to coalesced accesses from global memory wihtin a kernel.
int *h_val1, *h_val2; // allocate arrays in the host and initialize them
Let be N the size of the arrays, allocate the arrays in device memory
int *d_val1, *d_val2;
cudaMalloc( (void**) &d_val1, N * sizeof(int) );
cudaMalloc( (void**) &d_val2, N * sizeof(int) );
and copy data from host to device memory
cudaMemcpy(h_val1, d_val1, N * sizeof(int), cudaMemcpyHostoToDevice);
cudaMemcpy(h_val2, d_val2, N * sizeof(int), cudaMemcpyHostoToDevice);
Configure and launch your kernel to run as much threads as element in the array.
// kernel configuration
dim3 dimBlock = dim3 ( BLK_SIZE, 1, 1 );
dim3 dimGrid = dim3 ( (N / BLK_SIZE) + 1 );
yourKernel<<<dimGrid, dimBlock>>>(d_val1, d_val2);
With this in mind, implement your kernel
__global__ void
yourKernel(int* val1, int* val2, N)
{
// map from threadIdx/BlockIdx to index position
int gid = threadIdx.x + blockIdx.x * blockDim.x;
if (gid < N)
{
int r_val1 = val1[ idx ]; // load from global memory to register
int r_val2 = val2[ idx ]; // load from global memory to register
// do what you need to do with pair val1:val2
}
}
Do not forget to check for errors when calling CUDA functions.
Instead of storing something that references two ints, store something that holds a copy of the ints.
struct list_el {
int val; //first value
int val2; //second value
struct list_el * next;
};
typedef struct list_el item;
Sometimes it is preferable to hold a reference, sometime it is preferable to hold a value. Depending on what you are attempting to do, use the right tool for the job.
By the way, your reference holding struct was only holding references to shorts. To really hold references to ints, you need
struct list_el {
int *val; //reference to first value
int *val2; //reference to second value
struct list_el * next;
};
typedef struct list_el item;
Note that if you hold a reference, the rest of your program should not dispose of the reference's memory before you dispose of the struct reference to prevent accessing memory that is no longer associated with the program (which is an error).
There are other techniques, if you don't want to use list like constructs.
int val[2] = { 1, 2 };
will store two ints, but only two ints.
int val[2][9];
will store nine pairs of two ints, and could easily also be represented as
int val[9][2];
And of course, there is the old standby
int val = 3;
int val2 = 4;
How about just using a two-dimensional array?
int pairs[30][2];
pairs[0][0] = 10;
pairs[0][1] = 5;
// etc.
I'd have to test it, but I think I tested it, and you can even do something like
int pairs[][2] = {{10, 5}, {20, 40}, ...};
for initialization.
NOTE: This method works well if you know how many pairs you will have ahead of time and the number doesn't grow/shrink (in large amounts). If you have a widely variable number of pairs, sticking with a list of structs and using Edwin's answer would probably be better in the long run.
Having a two dimensional array is a good solution, but I am going to answer as if you are keeping your struct solution.
There's nothing wrong with your storing the short ints in a struct, but I would not store the values in short *. To me it is not worth dynamically allocating memory as you need a new structure.
You could have an array of structs to store this data. Here is an example of a fixed size array of item.
#include <stdio.h>
struct list_el {
short val; //first value
short val2; //second value
};
typedef struct list_el item;
item listA[20];
int main()
{
listA[0].val = 1;
listA[0].val2 = 2;
printf("\n%i %i\n", listA[0].val, listA[0].val2);
return 0
}
Even if you make the argument that you won't know in advance how many of these
structs you will have, I would only allocate space for the array like this:
#include <stdio.h>
#include <stdlib.h>
struct list_el {
short val; //first value
short val2; //second value
};
typedef struct list_el item;
item * p_list_el, * pCurStruct;
int main()
{
int idx;
/* p_list_el is the pointer to the array. Don't modify.
pCurStruct can be modified to walk the array. */
p_list_el = malloc(sizeof(item) * 20);
for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
{
pCurStruct[idx].val = idx;
pCurStruct[idx].val2 = idx + 1;
}
for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
{
printf("\n%i %i\n", pCurStruct[idx].val, pCurStruct[idx].val2);
}
free(p_list_el);
}

2D array problem

I need to make one 2D array in which one column store the pointer of some structure & another column store one 32 bit magic number.
how can i do it in 2D array.?
or any other method to keep track of this two columns info?
You can use:
// The struct that will hold the pointer and the magic number
struct data {
void *other_struct_ptr;
unsigned int magic_number;
};
// Declare my array
struct data array[N];
Where N is the size of your array. Now just fill your data into the array. For example:
array[0].other_struct_ptr = NULL; // I used NULL for simplicity
array[0].magic_number = 0xDEADC0DE;
array[1].other_struct_ptr = NULL;
array[1].magic_number = 0xCAFEBABE;
Define a struct like this:
struct data_t
{
void *pointer;
int magic_number;
};
Then use following array:
data_t values[100]; //100 is just for example
Or maybe you need such 2D array:
data_t values[100][100]; //100s are just for example

invalid use of flexible array -flexible struct array as a member of another struct

I'm beginning to learn about the use of structs in C. It's challenging and enjoyable. Needless to say I've encountered a problem I can't seem to figure out. I'm trying to make a flexible struct array as a member of another struct but I'm getting an error:
invalid use of flexible array
What am I doing wrong?
#define NUM_CHANNELS 4
struct channelStruct {
float volume;
uint mute;
};
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
struct channelStruct channels[];
};
struct enginestruct engine, *engineptr;
struct channelStruct channel, *channelptr;
-(void) setupengine
{
engineptr = &engine;
engineptr->oneBeatInSamples = 22050;
engineptr->samplerate = 44100;
struct channelStruct *ch = (struct channelStruct *) malloc (
NUM_CHANNELS*sizeof(struct channelStruct) );
//error occurs here
engineptr->channels = ch;
}
EDIT 1
It's something like this I am trying to achieve
flexible length struct array inside another struct using C
EDIT 2*
O.K so I seem to be approaching the creation of a variable sized array of struct the wrong way. I have 2 things that I'm trying. The first I know works for sure. The second I would just like if somebody could sanity check it for me. I'm still learning about pointers and would like to know if A is the same as B. B would be my preferred method but I don't know if its correct. I'm confident about a because when I debug channels i see channel[0],channel[1]channel[2] etc. But I'm not so confident about B because when I debug it I only see an address to memory and the variables of channel struct listed.
A
// pretty sure this is o.k to do but I would prefer
// not to have to set the size at compile time.
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
channel channels[NUM_CHANNELS]; //is this technically a pointer?
};
B
//I'm not sure if this is valid. Could somebody confirm for me if
//it is allocating the same amount of space as in A.
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
channel *channels;
};
//This only works if channel in the engine struct is defined as a pointer.
channel * ar = malloc(sizeof(*ar) * NUM_CHANNELS);
engineptr->channels = ar;
**EDIT 3****
Yep they are the same. Not sure when you would use one over the other tho
channel channels[NUM_CHANNELS];
Is Equal To :)
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
channel *channels;
};
channel * ar = malloc(sizeof(*ar) * NUM_CHANNELS);
engineptr->channels = ar;
Edit
I think I remember now what the problem is. When you declare a struct with a flexible array as it's last member it's doing something completely different than what you think.
struct channelStruct channels[];
is NOT a pointer, it is an in place array which is contiguous with the struct.
The way this is intended to be used is to lay the struct over an existing block memory. For instance, this is useful in networking when you have a packet with variable length data. So you might do something like:
struct mydata {
// various other data fields
int varDataSize;
char data[];
}
When you receive a packet you cast a pointer to the data to a mydata pointer and then the varDataSize field tells you how much you've got. Like I said, the thing to remember is that it's all one contiguous block of memory and data is NOT a pointer.
Old Answer:
I think that's only allow in the C99 standard. Try compiling with the -std=c99 flag.
Also, see this thread, Variable array in struct
Also see this SO post: Flexible array members in C - bad?
I am not an expert in this C feature but my common sense tells me that you cannot define objects of the type struct enginestruct, only pointers. This regards the engine variable in the following line:
struct enginestruct engine,*engineptr;

Resources