Pointer inside a structure not changing when passing by reference C - c

So, I'm pretty new to the C language and I've been passed a project by my professor to make a game in C. My problem is, I created a structure like so:
typedef struct vector
{
int parts;
int dir;
} Vector;
typedef struct snake
{
Vector* parts;
Vector dir;
} Snake;
I'm trying to initialize the parts pointer within this function:
void init_snake(struct snake *snake, int size, int x, int y)
{
snake->parts = (Vector *)malloc(sizeof(Vector) * size);
for (int i = 0; i < size; i++)
{
//sets the body parts one after the other in a line
snake->parts[i].x = x - i * PIXEL_SIZE;
snake->parts[i].y = y;
}
//sets the snake direction to the left
snake->dir.x = 1;
snake->dir.y = 0;
}
But by doing that the array parts inside the snake pointer is not initialized as expected. By checking its size with sizeof(snake.parts) / sizeof(Vector) it returns 0. Any ideas of how to fix it?

It likely is working, you're just confused about sizeof. This operator measures the size (in bytes) of a type. If you ask for the size of a value, it uses the type of that expression instead.
This is a compile-time evaluation and therefore is not dynamic.
sizeof(snake.parts) is the same as sizeof(Vector*) which will be either 4 or 8 bytes depending on whether you are compiling to a 32-bit or 64-bit target. Therefore, it's not useful to determine the size of an allocation.
Generally, given a pointer, you cannot tell how large the allocation is. Usually this is handled by storing some kind of useful length somewhere else. For example, you could modify struct snake to include an element count for parts:
typedef struct snake
{
Vector* parts;
int parts_size;
Vector dir;
} Snake;
And set this value accordingly:
snake->parts = (Vector *)malloc(sizeof(Vector) * size);
snake->parts_size = size;

Related

glib how address to index g_ptr_array

I have 3 structures and I use GNOME glib library to have dynamic array.
typedef struct Neuron
{
//number of inputs into neuron
int NumInputs;
//growing array of weights for each input
GArray* ArrWeight;
}neuron;
typedef struct NeuronLayer
{
//number of neurons in layer
int NumNeurons;
//growing array of neurons
GPtrArray* ArrNeurons;
}layer;
typedef struct Net
{
int numInputs;
int numOutputs;
int numHiddenLayers;
int NeuronsPerHiddenLayer;
//each layer of neurons
GPtrArray* ArrLayers;
}net;
I want write cycle like that
for (k = 0; k < Net->ArrLayers->pdata[i].ArrNeuron->pdata[j].NumInputs; k++)
But I dont know how address to array. Compiler (clang say) :
member reference base type 'gpointer' (aka 'void *') is not
a structure or union.
structure of Gptrarray:
struct GPtrArray
{
gpointer *pdata;
guint len;
};
I think i should write something like that
Net->ArrLayers->pdata[i*sizeof(layer)].ArrNeurons->pdata[j*sizeof(neuron)].NumInputs
gpointer is a generic pointer. You are using it to store a pointer of a specific type. So to access its elements you must use a type cast.
I will first try to break your statement down. It currently looks like this:
Net->ArrLayers->pdata[i].ArrNeuron->pdata[j].NumInputs
I assume Net is a variable of type net *.
Net->ArrLayers is of type GPtrArray *.
Net->ArrLayers->pdata is of type gpointer *, i.e. void **, a pointer to a pointer.
Net->ArrLayers->pdata[i] is thus of type gpointer, i.e. void *, a pointer.
Now you want to access its element. Judging from your context, you want to interpret this pointer as a pointer to layer. However, the compiler doesn't know that. You need to tell the compiler.
So you should add a cast, (layer *)Net->ArrLayers->pdata[i].
Now since this is of type layer * and not layer, you still need -> instead of . to access its element, so it should now become:
((layer *)Net->ArrLayers->pdata[i])->ArrNeuron
Now you need to access pdata again. This is the same as the above, so I'll skip the explanation and show you the correct method:
((neuron *)((layer *)Net->ArrLayers->pdata[i])->ArrNeuron->pdata[j])->NumInputs
As you can see this is very messy. It would be better to split this into several statements to enhance readability, and by doing so you may even skip the casts:
int current_num_inputs(net * Net, size_t i, size_t j) {
layer *current_layer = Net->ArrLayers->pdata[i];
neuron *current_neuron = current_layer->ArrNeuron->pdata[j];
return current_neuron->NumInputs;
}
Then in your for loop:
for(k = 0; k < current_num_inputs(Net, i, j); k++) { // ...

User defined types with dynamic size in C

I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes. This structure's definition needs to be global since I am going to use that type thereafter in my program. It is necessary to have a dynamic size for this structure because I will have a HUGE database populated by that type of variables in the end.
The code I have right now is:
struct user_defined_integer;
.
.
.
void def_type(int num_bits)
{
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
return;
}
(which is not working)
The closest thing to my question, I have found, is in here:
I need to make a global array in C with a size inputted by the user
(Which is not helpful)
Is there a way to do this, so that my structure is recognized in the whole file?
When doing:
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
You should get the warning:
warning: useless storage class specifier in empty declaration
because you have an empty declaration. extern does not apply to user_defined_integer, but rather the variable that comes after it. Secondly, this won't work anyway because a struct that contains a variable length array can't have any linkage.
error: object with variably modified type must have no linkage
Even so, variable length arrays allocate storage at the point of declaration. You should instead opt for dynamic memory.
#include <stdlib.h>
typedef struct
{
int num_bits;
int* val;
} user_defined_integer;
void set_val(user_defined_integer* udi, int num_bits)
{
udi->num_bits = num_bits;
udi->val = malloc(num_bits/sizeof(int));
}
What you need is a VLA member, as asked about here. Basically, you declare a struct with a size field and one element's worth of storage as last member, and over-allocate it.
Imported from that question :
typedef struct Bitmapset {
int nwords;
uint32 words[1];
} Bitmapset;
Bitmapset *allocate(int n) {
Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof *p->words);
p->nwords = n;
return p;
}
I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes.
This is not possible in C, because C types are a compile-time thing and don't exist at all at run-time.
However, with a C99 conforming compiler, you might use flexible array member. You'll need a struct containing some members and ending with an array without any given dimension, e.g.
struct my_flex_st {
unsigned size;
int arr[]; // of size elements
};
Here is a way to allocate it:
struct my_flex_st *make_flex(unsigned siz) {
struct my_flex_st* ptr
= malloc(sizeof(struct my_flex_st) + siz * sizeof(int));
if (!ptr) { perror("malloc my_flex_st"); exit(EXIT_FAILURE); };
ptr->size = siz;
memset (ptr->arr, 0, siz*sizeof(int));
return ptr;
}
Don't forget to free it once you don't use it anymore.
Of course, you'll need to use pointers in your code. If you really want to have a global variable, declare it as e.g.
extern struct my_flex_st* my_glob_ptr;
Try this method-
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
struct user_defined_integer
{
int *val;
}user_int;
void memory_allocate(int num_bit)
{
int result;
result = (num_bit+CHAR_BIT-1)/CHAR_BIT; // since 8 bit =1 byte
user_int.val=malloc(result*sizeof(int));
if(user_int.val == NULL){
printf("Failed to allocate memory\n");
return ;
}
else
printf("Allocated %d bytes for val\n",result);
}
int main()
{
int num_bit;
printf("Enter the number of bits\n");
scanf("%d",&num_bit);
memory_allocate(num_bit);
// do your stuff here
free(user_int.val); // free the memory at the end;
return 0;
}

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 ;)

c define arrays in struct with different sizes

I need to define a struct for two types of objects. Both have exactly the same data structure and perform same tasks (member methods).
The ONLY difference is that the array sizes are different in the two types, one using SIZE_A, the other SIZE_B.
Duplicating the definition of the struct and functions is not wanted.
How could I use one type of 'struct', and initialize its arrays with different sizes?
#define SIZE_A 100
#define SIZE_B 200
typedef struct{
int matr[SIZE_A][SIZE_A]; // for another type matr[SIZE_B]
int arr[SIZE_A]; // for another type arr[SIZE_B]
int size; // will be initialized to SIZE_A or SIZE_B
int var1, var2;
}s;
void task1(s* si){
...
}
void task2(s* si){
...
Even with a union, the struct will be as big as the largest of the two arrays.
Do one of these:
Ignore the overhead of the biggest array size. (Use one array or a union)
Create a separate struct for each type.
Dynamically allocate the array with malloc.
I would make matr a flexible array at the end of your struct. Then, I would stick the arr array into the last row of matr.
typedef struct {
int size;
int var1, var2;
int matr[];
} s;
static inline int size_ok_s (int size) {
switch (size) {
case SIZE_A:
case SIZE_B:
return 1;
default:
break;
}
return 0;
}
s * create_s (int size) {
s *x = 0;
if (size_ok_s(size)) {
x = malloc(sizeof(*x) + sizeof(int[size+1]));
if (x) x->size = size;
}
return x;
}
To achieve a uniform interface, you can use a macro:
#define s_matr(x) ((int (*)[(x)->size])(size_ok_s((x)->size) ? (x)->matr : 0))
#define s_arr(x) (s_matr(x)[(x)->size])
So, to access the ith row and jth column of s *foo's matr, and its kth element of arr:
s *foo = create_s(SIZE_A);
/* ... */
s_matr(foo)[i][j] = 0;
s_arr(foo)[k] = 0;
Flexible array members are a new feature of C.99 described in §6.7.2.1 ¶16. Prior to C.99, C programmers often used what was known as the struct hack:
typedef struct {
int size;
int var1, var2;
int matr[1];
} s;
s * create_s (int size) {
s *x = 0;
if (size_ok_s(size)) {
x = malloc(sizeof(*x) + sizeof(int[size]));
if (x) x->size = size;
}
return x;
}
This is a hack since in C.89-90, indexing the matr array with a value greater than 0 is technically accessing an object beyond its boundary. However, it was a common practice, and widely portable. C.99 formally sanctioned the mechanism with the flexible array member, although it requires the syntax of not specifying a size in the array declaration.
Have the arrays be pointers and allocate to them (the appropriate size) as needed. Only downsize is access to the 2D array will be a little clumsy.

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);
}

Resources