Use a struct in a header file [ C - Linux ] - c

I tried to use an external struct but when I compile my c code I obtained this message:
subscripted value is neither array nor pointer nor vector.
Why?
messaggio.h
struct Request {
struct {
u_int data_len;
float *data_val;
} data;
bool_t last;
};
typedef struct Request Request;
main.c
#include "messaggio.h"
int main(void){
struct Request x;
x.data[0] = 4.6;
printf("%f\n",x.data[0]);
return 0;
}

The x.data is a struct, so you cannot use [] with it. Maybe you want x.data.data_val[0].
Try this code:
struct Request x;
x.data.data_len = 5; // initialize the length, use any value you need
x.data.data_val = (float *) malloc(x.data.data_len * sizeof(float));
x.data.data_val[0] = 4.6

x.data is a structure and not an array.
Use x.data.data_val[0] if that is what you are trying to access. However, you have not allocated any memory for data_val. I believe you are trying to assign a number to data_len and will need to allocate the memory to hold data_len values in data_val.

The type of struct Request#data is an anonymous struct { u_int, float } and not an array. Thus you can't use the [] operator on it.
You probably wanted to do:
x.data.data_val[0]

Related

Dynamic Memory Allocation for Pointers inside Struct

A question with the same title has been asked before on Stack Overflow but it isn't the answer I am a looking for.
I am trying to create a pointer to a dynamically-allocated array containing the pixel data.
This is how I try doing it.
struct Image {
int width;
int height;
int* pixels = malloc((width * height) * sizeof(int));
};
Error Message
But I am getting an error expected a ';'
The same code outside the struct works fine.
Can someone please explain to me why this errror occurs.
The same code outside the struct works fine.
Can someone please explain to me why this errror occurs.
This is because a struct in C is something different than a struct C#:
In C you cannot assign "default" values to struct members like this:
struct myStruct {
int a = 2;
int b = 4;
};
You can only assign initial constant values to a variable that has a struct type:
struct mystruct {
int a;
int b;
};
struct mystruct myvar = { 5, 6 }; /* myvar.a=5, myvar.b=6 */
... but because malloc() is a function call, the following line is also not possible in C:
struct Image myVariable = { 10, 20, malloc(200) };
You must initialize the field pixels "outside the struct".

Can you create an array of Structure inside of another structure in C language?

Aim : To create a structure of element having certain properties. Then utilize that structure type by creating it's array in another structure.
struct Element
{
int i;
int j;
int x;
};
struct Sparse
{
int r;
int c;
int n;
struct Element *ele;
ele = (struct Element *)malloc(n*sizeof(struct Element));
};
What I wish to know is that which part of the code am I not allowed to write while creating a structure.
The common way to do this is:
struct Element
{
int i;
int j;
int x;
};
struct Sparse
{
int r;
int c;
int n;
struct Element ele[0]; // Make a zero length array
};
struct Sparse* MakeNewSparse(size_t num_ele)
{
struct Sparse* sparse = malloc(sizeof(*sparse) + num_ele*sizeof(struct Element));
return sparse;
}
This works because accessing off the end of a zero-length array is totally legal in C, provided you have allocated memory there.
In this example, we allocate enough space for the struct Sparse, and then enough more contiguous space for the array of struct Element.
After that, accessing element sparse->ele[5] is totally legal.
The line
ele = (struct Element *)malloc(n*sizeof(struct Element));
should not be part of the struct definition - that's something you do at runtime, along these lines:
struct Sparse s; // create new struct Sparse instance
s.n = get_some_size();
s.ele = malloc( s.n * sizeof *s.ele ); // no need for cast
struct in c is syntactically similar with types like int, char, etc. The definition of a struct is for compiler to know how to use variable declared with that struct such as struct Sparse var;. So the definition of a struct is not actually the code itself. It will be used at compile time.
However, malloc() is a function, which will be used at runtime, so it is nonsense to put malloc() in your struct definition.

Writing an Address to a Pointer in a struct with a function fails

I have two structs pbuf and netif, and assigned two variables (local_pbuf, local_netif) with them. These variables hold some data. There is another struct called wrapper_p_n, which holds two pointers of the type pbuf and netif. My goal is to write a function which hand over the variables local_pbuf and local_netif by call by reference and then wraps the two pointers in a single struct called wrapper_p_n. Then I want to use call by reference to give wrapper_p_n to another function. Unfortunately I get the Error message:
[Error] cannot convert 'pbuf**' to 'pbuf*' in assignment
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
struct pbuf{
int a;
int b;
};
struct netif{
int c;
int d;
};
struct wrapper_p_n{ // wrapper for pbuf- and netif-struct pointer
struct pbuf *wp_val_p;
struct netif *wp_val_n;
};
void rx_local_p_n(struct pbuf *rx_pbuf, struct netif *rx_netif)
{
// wrap the received pointer
struct wrapper_p_n *local_w_p_n;
local_w_p_n->wp_val_p = &rx_pbuf;
local_w_p_n->wp_val_n = &rx_netif;
/*Passing *local_w_p_n pointer to another function: Example: */
/*ex_function(&local_w_p_n)*/
}
int main(int argc, char** argv) {
// give values to local_pbuf and netif
struct pbuf local_pbuf;
local_pbuf.a = 1;
local_pbuf.b = 2;
struct netif local_netif;
local_netif.c = 3;
local_netif.d = 4;
//passing pbuf- and netif-stuct to function
rx_local_p_n(&local_pbuf, &local_netif);
return 0;
}
In the function void rx_local_p_n you pass in pointers to the pbuf and netif struct. These are already pointers and do not need to be assigned to your wrapper struct using the address of operator (&): by doing so you are getting the memory location of the pointer itself. That is why it is complaining about not being able to convert pbuf** to pbuf*.
Solution
local_w_p_n->wp_val_p = &rx_pbuf; to local_w_p_n->wp_val_p = rx_pbuf;
local_w_p_n->wp_val_n = &rx_netif; to local_w_p_n->wp_val_n = rx_netif;
Here in the function params,
struct pbuf *rx_pbuf, struct netif *rx_netif
Are already pointers, you do not need to get the address of the pointers, the & is useful when your variables are allocated on the stack and the function call needs a pointer.
As a result, this is the code change
local_w_p_n->wp_val_p = rx_pbuf;
local_w_p_n->wp_val_n = rx_netif;
In the original posted code local_w_p_n was defined as a pointer but not initialized; the attempts to assign members should crash since local_w_p_n would be leftover stack data, not a valid address. Try this example:
void rx_local_p_n(struct pbuf *rx_pbuf, struct netif *rx_netif)
{
// define as a struct instead of a struct *
struct wrapper_p_n local_w_p_n;
// assign from func args without &
// switch from -> to .
local_w_p_n.wp_val_p = rx_pbuf;
local_w_p_n.wp_val_n = rx_netif;
x_function(&local_w_p_n);
}

Handling arrays of C structs

I have a C
struct of the form :
#define RGB_TYPE 1
#define YUV_TYPE 2
#define MAX_LIST 20
typedef struct
{
uint16_t a[2];
uint8_t b;
float_t c;
} mystruct;
I have an array of mystruct like this
mystruct MyStructList[MAX_LIST]= {
{{100, 200}, RGB_TYPE, 25.0},
{{200, 400}, RGB_TYPE,25.0},
{{300,600} ,YUV_TYPE ,30.0},
{{400,600},YUV_TYPE, 30.0}
};
In my code I do the following ;
mystruct config;
int i = 0;
.....
for(i=0;i<4;i++)
{
config = MyStructList[i];
/* further processing on config */
some_func(i,&config);
}
int some_func(int x, mystruct* pstruct );
{
/* using pstruct values and storing them in internal arrays */
}
Is this sort of struct copy and handling valid ?
I am using mingw gcc
It looks OK, but note that config = MyStructList[i]; makes a shallow copy of the struct. If you want to operate on the original array, mystruct should be a pointer that takes the address of MyStructList[i].
For example:
for(i=0;i<4;i++)
{
mystruct * config = &MyStructList[i];
some_func(i, config);
}
Instead of saying config = MyStructList[i]; you should allocate the number of elements needed by using malloc. For example, in the loop body, you should say
mystruct * config = ( mystruct *) malloc ( i * sizeof ( mystruct ) );
some_func ( i, config ); // You do not have to use address because config is a pointer type now
free ( config );
This kind of copy is valid. It might not be efficient, you could just use a pointer to the original struct when calling some_func(). Then in some_func you store a copy of it's values in internal arrays.

Copy Struct to Array of Structs Received as Pointer Argument in Function

I've got a function that takes as an argument a pointer to an array of structs:
void foo (int *StructArrayAddress)
Within the function, I then build a new struct that looks like this
struct
{
int a;
int b;
char c[10];
}myStruct;
What I would then like to do is copy that struct to my array of structs based on the pointer to that array that I received as an argument. Not having any luck with the syntax, or I'm missing something. Can anyone advise?
Thanks!
EDIT: I'm not sure I explained myself correctly, as I don't think the solution posted here is what I want to do. To clarify: there is some array of structs outside my function here. I receive the address of the correct struct element in an array of structs as an argument to my function. Assume the caller already took care of passing me the correct address; I don't have to index it up at all.
I then locally build a struct from some other data. I now want to copy this struct that I built locally to the struct at the location in the array that I received as an argument.
void foo (int *StructArrayAddress)
{
struct
{
int a;
int b;
char c[10];
}myStruct;
a = 5;
b = 10;
c = {1,2,3,4,5,6,7,8,9,10};
//Copy local struct myStruct to location StructArrayAddress here
StructArrayAddress = myStruct; //Something like this but I have the syntax wrong
}
I hope that makes more sense.
EDIT2: I may have just realized something that you guys have been trying to convey to me that I was missing: is a reference to my local struct needed in the argument somehow so that the format of the structure as I pass it back is known?
Your function definition should be like
void foo (myStruct *StructArrayAddress, int index)
{
myStruct x;
x.a = 1;
x.b = 2;
strncpy(x.c, "Test", 9);
/* Now copy this struct to the array of structs at index specified by second argument */
memcpy((StructArrayAddress + index), &x, sizeof(myStruct));
}

Resources