I am implementing a PSO Algorithm. I use this
data structure:
typedef struct {
float x;
float y;
} C_struct_Class2D;
typedef struct {
C_struct_Class2D *pos;
C_struct_Class2D *best_pos;
C_struct_Class2D *vel;
} C_struct_Particle;
typedef struct { <br>
C_struct_Particle **particles;
C_struct_Particle *g;
} C_struct_Swarm;
I have to work with C, not with C++. That's why I use structs instread of classes.
Description of the strucs:
There is a Swarm(C_struct_Swarm) which consists of several Particles(**particles) an an optimum Particles(*g). Each Particle has a Position, Best Position and Velocity of Type
"C_struct_Class2D".
In a few methods I allocate memory space for each data and initialize it. But I' like
the whole data structure to be continuous in the memory. So that all structs are
behind each other in the address space.
The memory should look like:
C_struct_Swarm
particles[0]
particles[0]->pos
particles[0]->best_pos
particles[0]->vel
particles[1]
particles[1]->pos
particles[1]->best_pos
particles[1]->vel
...
...
...
...
particles[n]
particles[n]->pos
particles[n]->best_pos
particles[n]->vel
g->pos
g->best_pos
g->vel
How can I achieve this?
Regards
sw
Compose members by value
Include C_struct_Class2D by value inside C_struct_Particle:
typedef struct {
C_struct_Class2D pos;
C_struct_Class2D best_pos;
C_struct_Class2D vel;
} C_struct_Particle;
This guarantees the order of those members (pos is before best_pos is before vel).
Allocate an array of items, instead of an array of pointers to items
typedef struct {
C_struct_Particle *particles;
int num_particles;
C_struct_Particle g;
} C_struct_Swarm;
I should note that here, the data pointed to by particles is NOT contiguous with the other members, so what you are asking for is not entirely possible, unless you do something else like set g to always be the first particle, i.e. included in the particles "array".
Watch out for padding
If you don't care about padding (and in your code example it looks like you don't), then skip this. Otherwise it's platform/compiler specific. In GCC for example, you can use the packed attribute:
struct __attribute__ ((__packed__)) my_packed_struct
{
char c;
int i;
};
You cannot in the way you have described. If you want continuous blocks of memory, the only solution (as far as I know) is to use buffers (see my similar answer that might give you an idea how to implement it).
If you use gcc, for static object you could try __attribute__... more info here http://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Variable-Attributes.html
iw source code as example
Related
Trying to create a struct that contains three arrays. I'm unsure of how large to make the arrays until the input is read.
How can i initialize these arrays in the struct if i'm unsure how large they are going to be in the struct init? I will know the total amount from the first line of input.
I would be the size that is read in from the use input. Should I just make i a huge number?
struct TaskSet
{
float priority[i];
float p[i];
float w[i];
float d[i];
};
You can either use a huge number or use T *arr (together with the size):
struct TaskSet
{
float *priority;
int size_priority;
...
float *d;
int size_d;
};
P.S.: You need to use malloc with the size once read from the user.
A struct needs to be a known size at compile-time so that the compiler knows how much space to give each one in memory. Consider the following struct:
struct pair{
int a;
int b;
};
When you create a struct as a function variable, the compiler creates enough space for two ints on the stack. If you create an array of five structs (see below) the compiler creates enough space for 2*5=10 contiguous ints on the stack:
struct pair p[5];
It is not possible for the compiler to create a struct on the stack if it does not know the size of the struct ahead of time.
Pointers are always the same size, so I recommend using a struct of pointers, like in herohuyongtao's sample code.
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.
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.)
I want the size of a C struct to be multiple of 16 bytes (16B/32B/48B/..).
It does not matter which size it gets to; it only needs to be multiple of 16 bytes.
How could I enforce the compiler to do that?
For Microsoft Visual C++:
#pragma pack(push, 16)
struct _some_struct
{
...
}
#pragma pack(pop)
For GCC:
struct _some_struct { ... } __attribute__ ((aligned (16)));
Example:
#include <stdio.h>
struct test_t {
int x;
int y;
} __attribute__((aligned(16)));
int main()
{
printf("%lu\n", sizeof(struct test_t));
return 0;
}
compiled with gcc -o main main.c will output 16. The same goes for other compilers.
The size of a C struct will depend on the members of the struct, their types and how many of them there are. There is really no standard way to force the compiler to make structs to be a multiple of some size. Some compilers provide a pragma that will allow you to set the alignment boundary however that is really a different thing. And there may be some that would have such a setting or provide such a pragma.
However if you insist on this one method would be to do memory allocation of the struct and to force the memory allocation to round up to the next 16 byte size.
So if you had a struct like this.
struct _simpleStruct {
int iValueA;
int iValueB;
};
Then you could do something like the following.
{
struct _simpleStruct *pStruct = 0;
pStruct = malloc ((sizeof(*pStruct)/16 + 1)*16);
// use the pStruct for whatever
free(pStruct);
}
What this would do is to push the size up to the next 16 byte size so far as you were concerned. However what the memory allocator does may or may not be to give you a block that is actually that size. The block of memory may actually be larger than your request.
If you are going to do something special with this, for instance lets say that you are going to write this struct to a file and you want to know the block size then you would have to do the same calculation used in the malloc() rather than using the sizeof() operator to calculate the size of the struct.
So the next thing would be to write your own sizeof() operator using a macro such as.
#define SIZEOF16(x) ((sizeof(x)/16 + 1) * 16)
As far as I know there is no dependable method for pulling the size of an allocated block from a pointer. Normally a pointer will have a memory allocation block that is used by the memory heap management functions that will contain various memory management information such as the allocated block size which may actually be larger than the requested amount of memory. However the format for this block and where it is located relative to the actual memory address provided will depend on the C compiler's run time.
This depends entirely on the compiler and other tools since alignment is not specified that deeply in the ISO C standard (it specifies that alignment may happen at the compilers behest but does not go into detail as to how to enforce it).
You'll need to look into the implementation-specific stuff for your compiler toolchain. It may provide a #pragma pack (or align or some other thing) that you can add to your structure defininition.
It may also provide this as a language extension. For example, gcc allows you to add attributes to a definition, one of which controls alignment:
struct mystruct { int val[7]; } __attribute__ ((aligned (16)));
You could perhaps do a double struct, wrapping your actual struct in a second one that can add padding:
struct payload {
int a; /*Your actual fields. */
float b;
char c;
double d;
};
struct payload_padded {
struct payload p;
char padding[16 * ((sizeof (struct payload) + 15) / 16)];
};
Then you can work with the padded struct:
struct payload_padded a;
a.p.d = 43.3;
Of course, you can make use of the fact that the first member of a structure starts 0 bytes from where the structure starts, and treat a pointer to struct payload_padded as if it's a pointer to a struct payload (because it is):
float d_plus_2(const struct payload *p)
{
return p->d + 2;
}
/* ... */
struct payload_padded b;
const double dp2 = d_plus_2((struct payload *) &b);
I have a nested structure as follows:
typedef struct {
float mz_value;
float int_value;
} spectrum;
typedef struct {
// stuff
spectrum* spectra; /* Nested struct */
// more stuff
} chromatogram;
I allocate memory in my code as follows:
(chrom+i)->spectra=malloc(sizeof(spectrum)*1024);
I then want to assign some values to it and I have been trying all kinds of syntaxes similar to:
((chrom+i)->(spectra+j))->mz_value = (float)*(array_buffer+j);
// array_buffer is a float*
Yet this keeps giving me an error that I am failing at proper usages of braces, the only problem is that I can't figure out where o.O Any help would be greatly appreciated before I regret trying to use a nested structure.
Cheers,
Bas
Try
((chrom+i)->spectra+j)->mz_value = (float)*(array_buffer+j);
Or, preferably, use array notation, which is much clearer in this case:
chrom[i].spectra[j].mz_value = (float)array_buffer[j];
Your spectra value is not a statically allocated structure it's a pointer
and you need allocate memory for it.
If you are going to work with fixed number of spectrum items
use statically allocated array
spectrum spectra[someConstantValue];
or allocate/free it dynamically, in this case you also need to hold number of elements.
typedef struct {
// stuff
spectrum* spectra; /* Nested struct */
int count;
// more stuff
} chromatogram;