gcc: Forward pointer address with sizeof value - c

Working with this code:
#include <stdlib.h>
#include <stdio.h>
int j_btree_create (int fn_initial_nodes);
typedef struct {
int depth;
int value;
void *item;
void *left_pointer;
void *right_pointer;
} j_btree_node_int;
typedef struct {
int nodes;
int available_nodes;
int btree_extension;
} j_btree_descriptor_int;
int j_btree_create (int fn_initial_nodes) {
int *free_btree_node;
int loop_counter;
j_btree_descriptor_int *btree_start;
btree_start = (j_btree_descriptor_int *) malloc (((sizeof(j_btree_node_int) + sizeof(free_btree_node)) * fn_initial_nodes) + sizeof(j_btree_descriptor_int));
(*btree_start).nodes = fn_initial_nodes;
(*btree_start).available_nodes = fn_initial_nodes;
(*btree_start).extension = NULL; */
for (loop_counter = 0; loop_counter < fn_initial_nodes; loop_counter++) {
printf ("loop_test: %d", loop_counter);
}
}
I want a pointer that points to the location after the binary tree descriptor (basically a struct at btree_start)
Can I do this with by
free_btree_node = btree_start + sizeof(j_btree_descriptor_int);
Or is this liable to go completely wrong? If so how should I do this? I will be doing something similar to initially populate the table of unused binary tree nodes.

If you really want to keep it all in one structure, one approach is to use a 'flexible array member':
typedef struct {
int *value;
j_btree_node_int node;
} j_btree_node;
typedef struct {
j_btree_descriptor_int btree_start;
j_btree_node nodes[0];
} j_btree;
j_btree *btree = malloc(sizeof(j_btree) + fn_initial_nodes * sizeof(j_btree_node));
free_btree_node = &j_btree->nodes[0];

You ask about
free_btree_node = btree_start + sizeof(j_btree_descriptor_int);
Because of the rules of pointer arithmetic, which implicitly multiply an offset by the type's size, that's equivalent to
free_btree_node = &btree_start[sizeof(j_btree_descriptor_int)];
which isn't what you want. What you want is
free_btree_node = (int*)&btree_start[1];
or, equivalently,
free_btree_node = (int*)(btree_start + 1);
Yes, you can do that, since you allocated extra space. But it doesn't really make sense, because you allocated ((sizeof(j_btree_node_int) + sizeof(free_btree_node)) * fn_initial_nodes) extra bytes, which is not a count of ints. It's not clear what you want that to be, but it certainly can't be right because free_btree_node is a pointer and you have no interest in its size ... you probably meant sizeof(*free_btree_node). But your code is impenetrable because there are no comments explaining what things are or why you are doing things. In particular, there should be a comment on your malloc saying exactly what it is you think you are allocing ... maybe even a little diagram. Or you could forego trying to allocate contiguous structures and allocate each sort of thing independently.
(*btree_start).nodes
Please use
btree_start->nodes
It's standard usage, more succinct, more comprehendible ...

Related

Can I iterate dynamic array without knowing the size of it

I allocated some data in a dynamic array of a struct. Can I iterate that struct * without knowing it's size somehow?
Would this work?
int main() {
struct *foo = NULL;
//struct filling
iterate_foo(foo);
}
void iterate_foo(struct *foo) {
int i=0;
while (foo[i] != NULL) { // Would this work?
//something
}
}
The only way that can work is if you have a sentinel value in the array that indicates the end. Strings in C work that way.
For instance, if you invoke strcpy(a, b), then characters from b will be copied to a until and including the value zero. If there's no zero terminator within the b array, or if a is not big enough to hold all the characters, the function call leads to undefined behavior.
If you don't want to use a sentinel value, you have the option of passing the size as a separate parameter. Another way is to wrap things in a container struct, like this:
struct container {
struct mystruct *data;
size_t size;
}
Furthermore, struct *foo = NULL; is wrong. It has to be something like struct mystruct *foo = NULL;
But if you have this code:
void foo(T *ptr) {
// Do something
}
int main(void) {
T *a = malloc(N * sizeof *a);
T b[N];
foo(a);
foo(b);
}
Then it's completely impossible for foo to figure out N in a portable way. In some cases, believe that the implementation of malloc stores the size right before the data. But don't try to exploit that. It will only cause severe head ache.

Creating an Instance of a struct

I have this struct
struct FluxCapacitor{
unsigned char* c_string;
unsigned int value;
};
Now I need to create an instance of this struct. I googled this problem and found that I have to use something like this
typedef struct FluxCapacitor{
unsigned char* c_string
unsigned int value;
};
But I dont really understand the next step with malloc(). Can someone explain it to me?
You do not need malloc() to create an instance of a struct. And I would recommend that you avoid typedefing structures merely to reduce keystrokes. The extra keystrokes would only be saved in declarations and function prototypes (and maybe if you need to cast something), since you don't need the struct keyword elsewhere; the advantage is that when you see struct FluxCapacitor, you know exactly what it is. If you only see FluxCapacitor alone, you don't know if it is a typedef for a struct, or a union, or an integer type or what.
Note that the posted code was missing the semicolon at the end of the declaration. Also, it is unclear why you have unsigned char* c_string;. This may not allow assignment to a string literal. I have changed this in the code below. You can create a single struct like this:
struct FluxCapacitor
{
char *c_string;
unsigned int value;
};
...
struct FluxCapacitor fcap_1;
You can then assign values to the fields of fcap_1:
fcap_1.c_string = "McFly";
fcap_1.value = 42;
Note that you could also use designated initializers at the point of declaration:
struct FluxCapacitor fcap_2 = { .c_string = "Biff",
.value = 1985
};
If you need an array of FluxCapacitor structures, just declare one:
struct FluxCapacitor fcaps[2];
You can assign to the fields of each array member in a loop:
struct FluxCapacitor fcaps[2];
char *somestrings[] = { "McFly", "Biff" };
unsigned somevalues[] = { 42, 1985 };
for (size_t i = 0; i < 2; i++) {
fcaps[i].c_string = somestrings[i];
fcaps[i].value = somevalues[i];
}
Alternatively, you can use designated initializers here too:
struct FluxCapacitor fcaps[2] = { { .c_string = "McFly", .value = 42 },
{ .c_string = "Biff", .value = 1985}
};
Using malloc()
Since OP seems determined to use malloc(), it would be good to first recall that memory allocated with malloc() must later be deallocated with free(). Also note that malloc() can fail to allocate memory, returning a null pointer. Thus the result of a call to malloc() must be checked before attempting to dereference this pointer. The additional complexity should be avoided in favor of the above approaches unless OP has good reason to do manual allocation.
In the code below, the function create_flux_cap() takes a string and an unsigned int as arguments, and returns a pointer to a newly allocated FluxCapacitor structure with the arguments assigned to the appropriate fields. Note that since the FluxCapacitor structure is accessed through a pointer, the arrow operator is used instead of the dot operator.
Inside the function, the return value from the call to malloc() is checked before attempting assignment. If the allocation has failed, no assignment is made and a null pointer is returned to the calling function. Note that in the call to malloc(), the result is not cast, since there is no need for this in C and it needlessly clutters the code. Also observe that an identifier is used instead of an explicit type with the sizeof operator. This is less error-prone, easier to maintain if types change in the future, and is much cleaner code. That is, instead of this:
new_fcap = (struct FluxCapacitor *)malloc(sizeof (struct FluxCapacitor));
use this:
new_fcap = malloc(sizeof *new_fcap);
In main(), the return values from the calls to create_flux_cap() are checked. If an allocation has failed, the program exits with an error message.
The stdlib.h header file has been included for the function prototypes of malloc() and exit(), and also for the macro EXIT_FAILURE.
#include <stdio.h>
#include <stdlib.h>
struct FluxCapacitor
{
char* c_string;
unsigned value;
};
struct FluxCapacitor * create_flux_cap(char *, unsigned);
int main(void)
{
struct FluxCapacitor *fcap_1 = create_flux_cap("McFly", 42);
struct FluxCapacitor *fcap_2 = create_flux_cap("Biff", 1985);
/* Check for allocation errors */
if (fcap_1 == NULL || fcap_2 == NULL) {
fprintf(stderr, "Unable to create FluxCapacitor\n");
exit(EXIT_FAILURE);
}
/* Display contents of structures */
printf("%s, %u\n", fcap_1->c_string, fcap_1->value);
printf("%s, %u\n", fcap_2->c_string, fcap_2->value);
/* Free allocated memory */
free(fcap_1);
free(fcap_2);
return 0;
}
struct FluxCapacitor * create_flux_cap(char *str, unsigned val)
{
struct FluxCapacitor *new_fcap;
new_fcap = malloc(sizeof *new_fcap);
if (new_fcap != NULL) {
new_fcap->c_string = str;
new_fcap->value = val;
}
return new_fcap;
}
You need malloc for dynamic allocation of memory.In your case, both the types char and int are known to the compiler, it means the compiler can know the exact memory requirement at compile time.
For e.g. you can create a struct object like in the main function
#include<stdio.h>
#include<stdlib.h>
struct FluxCapacitor{
unsigned char* c_string;
unsigned int value;
};
int main() {
FluxCapacitor x;
x.c_string = "This is x capacitor"
x.value = 10
}
The x is of value type. You can make a copy and pass around this value. Also, observe we are using . notation to access its member variables.
But this doesn't happen at all time. We are not aware of future FluxCapacitor requirement and so above program will need more memory as while it is running and by using the malloc we can ask the compiler to provide us requested memory. This is a good place to use malloc, what malloc does is, it returns us a pointer to a piece of memory of the requested size. It is dynamic memory allocation.
Here's a simple example: let suppose if you need struct declaration of FluxCapacitor but don't know how many you will need, then use malloc
#include<stdio.h>
#include<stdlib.h>
typedef struct FluxCapacitor {
unsigned char* c_string;
int value;;
} flux;
// typedef is used to have the alias for the struct FluxCapacitor as flux
int main() {
flux *a = malloc(sizeof(flux)); // piece of memory requested
a -> c_string = "Hello World"; // Pointer notation
a -> value = 5;
free(a); // you need to handle freeing of memory
return 0;
}
.

How to fix allocated memory from a struct hack in a different method?

I'm developing a driver in C for communication and the messages exchanged don't have a fixed size. The recommendation of communication bus is to use structs for multi-topics, which is also my case.
My 1st problem: I have to keep listening for new messages, and when I get one I have to process message data (it has a delay) and still listening for new messages.
1st solution: using thread when got new messages to process data.
My 2nd problem: Data in message can have multiple data of a struct, and my communicator requires using a struct to organize this multiple values.
2nd solution: using struct hack to allocate memory dynamic size of struct.
My current problem: when I'd pass my struct as argument to the thread, or any function, I'm loosing data structure and getting wrong values.
A short test which a made is:
typedef struct test{
int size;
int value[];
} test;
void allocation(test *v){
test *aux = (test *)malloc(sizeof(test)+3*sizeof(int));
int i;
aux->value[0] = 2;
aux->size = 3;
aux->value[1] = 1;
aux->value[2] = 5;
printf("Teste1 %d\n",aux->size);
for(i=0; i < aux->size; i++){
printf("%d\n", aux->value[i]);
}
*v = *aux;
}
void cleanup(test *v){
free(v);
}
int main(int argc, char *argv[]){
test v;
int i;
allocation(&v);
printf("Teste2 %d\n",v.size);
for(i=0; i < v.size; i++){
printf("%d\n", v.value[i]);
}
//cleanup(&v);
return 0;
}
In this test I got right values in first print and wrong values in second (only v.size is giving a right value).
And my struct is a little more complex than that in test. My struct is like:
typedef struct test1{
double v1;
double v2;
} test1;
typedef struct test2{
int size;
test1 values[];
} test2;
Do you know how to fix my memory struct in that function, once I have all elements necessary to fix? Please, keep in mind that is desirable (not required) that I could also allocate multiple test2 data.
The thing here is that you assign structs with incomplete member int value[]; Though it is in principle OK to copy two structs by value (and this is actually what happens if you write *v = *aux); However, as the compiler does not know which size member value[] will take on at runtime, the "sizeof" of v as well as the size of *aux is always 4, i.e. the known size of the one int member size. Hence, only this is copied, whereas the value[]-array simply gets not copied.
A way out out this situation would be require a pointer to a pointer (i.e. allocation(test **v), such that the memory reserved can be directly assigned to it, using a pointer to struct test in main, i.e. test *vptr, and call allocation(&vptr).
If you cannot avoid passing a reverence to the value (instead of a reference to a pointer to the value), I suppose you'll have to use memcpy to transfer the contents. But this does actually not make sense, because then the receiver must provide enough space to take on the value[]-array in advance (which is not the case if you simple declare a variable of the form test v). An then the malloc and the aux would make no sense; you could directly write into object v passed by reference.
You are declaring v as non-pointer, meaning that the memory is already allocated for v when you declare it in main. Sending the reference to your allocation only copies the size correctly since it is not dynamically allocated. Correct way to do this would be to:
Declare your v as pointer
Make your allocation return test* (test* allocation())
Assign it to v in main. i.e. something like v = allocate()
And use v like a pointer from then on
EDIT: Since OP wants this to work only as arguments, best way to go about it is using double pointer. Check the following code:
typedef struct test{
int size;
int value[];
} test;
void allocation(test **v){
test *aux = (test *)malloc(sizeof(test)+3*sizeof(int));
int i;
aux->value[0] = 2;
aux->size = 3;
aux->value[1] = 1;
aux->value[2] = 5;
printf("Teste1 %d\n",aux->size);
for(i=0; i < aux->size; i++){
printf("%d\n", aux->value[i]);
}
*v = aux;
}
void cleanup(test *v){
free(v);
}
int main(int argc, char *argv[]){
test **v;
v = malloc (sizeof (test*));
int i;
allocation(v);
printf("Teste2 %d\n",(*v)->size);
for(i=0; i < (*v)->size; i++){
printf("%d\n", (*v)->value[i]);
}
//cleanup(&v);
return 0;
}
Please note that your cleanup will change too after this.

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

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