It looks like you're not allocating space for your states in the machine past the first one.
StateMachine * create_state_machine(const char* name) {
StateMachine * temp;
temp = malloc(sizeof(struct StateMachine));
if (temp == NULL) {
exit(127);
}
temp->name = name;
temp->total_states = 0;
temp->states = malloc(sizeof(struct State)); // This bit here only allocates space for 1.
return temp;
}
You're probably better off putting an array of states of fixed size in the state machine struct. If that's not okay, you'll have to realloc and move the whole set around or allocate chunks and keep track of the current length, or make a linked list.
Incidentally, init, foo, and bar never get used.
Edit: What I'm suggesting looks like this:
#define MAX_STATES 128 // Pick something sensible.
typedef struct StateMachine {
const char * name;
int total_states;
State *states[MAX_STATES];
} StateMachine;
Answer from nmichaels on Stack OverflowIt looks like you're not allocating space for your states in the machine past the first one.
StateMachine * create_state_machine(const char* name) {
StateMachine * temp;
temp = malloc(sizeof(struct StateMachine));
if (temp == NULL) {
exit(127);
}
temp->name = name;
temp->total_states = 0;
temp->states = malloc(sizeof(struct State)); // This bit here only allocates space for 1.
return temp;
}
You're probably better off putting an array of states of fixed size in the state machine struct. If that's not okay, you'll have to realloc and move the whole set around or allocate chunks and keep track of the current length, or make a linked list.
Incidentally, init, foo, and bar never get used.
Edit: What I'm suggesting looks like this:
#define MAX_STATES 128 // Pick something sensible.
typedef struct StateMachine {
const char * name;
int total_states;
State *states[MAX_STATES];
} StateMachine;
It looks like you want to have a variable number of states in each state machine, but you are allocating the memory incorrectly. In create_state_machine, this line:
temp->states = malloc(sizeof(struct State));
Allocates a single State object, not an array of pointers (which is how you are using it).
There are two ways you could change this.
- Declare
statesasState states[<some-fixed-size>];but then you cant ever have more than a fixed number of states. - Add another member to indicate how much storage has been allocated for
states, so you can keep track of that as well as how much is used (which is whattotal_statesis being used for).
The later would look something like this:
#include <stdlib.h>
#include <string.h>
typedef struct
{
const char *name;
} State;
typedef struct
{
const char *name;
int total_states;
int states_capacity;
State *states;
} StateMachine;
StateMachine *create_state_machine(const char *name)
{
StateMachine *temp = malloc(sizeof(StateMachine));
memset(temp, 0, sizeof(*temp));
temp->name = name;
temp->states_capacity = 10;
temp->states = malloc(sizeof(State) * temp->states_capacity);
return temp;
}
State *add_state(StateMachine *machine, const char *name)
{
if (machine->total_states == machine->states_capacity)
{
// could grow in any fashion. here i double the size, could leave
// half the memory wasted though.
machine->states_capacity *= 2;
machine->states = realloc(
machine->states,
sizeof(State) * machine->states_capacity);
}
State *state = (machine->states + machine->total_states);
state->name = name;
machine->total_states++;
return state;
}
I have participated in many coding competitions but I'm unable to pass all the test cases just because of this problem. I don't know how to initialize an array with unknown size. I tried using
arr=malloc(size*sizeof(int));
But at the end it shows segmentation fault. Can someone explain why?
Struct unknown size
c - Pointer in Struct -- unknown sized array - Stack Overflow
gcc - C Struct array member without specific length - Stack Overflow
c++11 - C++ How to initialize array in struct of unknown size - Stack Overflow
value is not array, it's a pointer (which is pointing somewhere outside the struct). If you want array (of unknown size), write unsigned char value[1] instead.
typedef struct __attribute__((packed)) {
unsigned char type;
unsigned char length;
unsigned char value[1];
} TLV;
Having an array of size 1 allows you to actually address any number of bytes. That is actually UB, but it is actually used and works properly in all cases I saw.
GCC allows to use arrays of size 0. I am so used to that convention that I forgot that arrays of size 0 are not allowed in C.
Edit:
Long answer
There is a difference between arrays and pointers. While you can use the similar code to work with both, these are still different beasts.
Disclaimer: The following code works in gcc, but it might not be strictly valid. I did not try to make it completely valid.
Let's define two structures:
typedef struct {
char p[20];
} sa;
typedef struct {
char *p;
} sp;
And create instances of those:
sa x = { "Hello, world" };
sp y = { "Howdy, world" };
What's the difference between those two?
printf("%s\n", x.p); // prints "Hello, world"
printf("%s\n", y.p); // prints "Howdy, world"
What about addresses of these?
printf("address of x = %p\n", &x); // On my machine it prints 0x7fffacce9b20
printf("address of y = %p\n", &y); // 0x7fffacce9b10
Well.. not really interesting except that these numbers are .. quite similar - both structures are located in about the same spot - in my case it's stack, end of address space, but could be somewhere else.
printf("address of x.p = %p\n", &x.p); // 0x7fffacce9b20
printf("address of y.p = %p\n", &y.p); // 0x7fffacce9b10
Same numbers. As expected actually.
printf("address of x.p[0] = %p\n", &x.p[0]); // 0x7fffacce9b20 - same as before
printf("address of y.p[0] = %p\n", &y.p[0]); // 0x400764 - could be anything
Now these are different. The string "Hello, world" is located in the same spot as structure x, while string "Howdy, world" is located somewhere else - data segment, somewhere in the beginning of address space, but, again could be somewhere else.
So this is the difference: array is some data stored "here", while pointer is only address of the data stored "somewhere".
In your case you want to be able to keep the data somewhere "here" - right after the type and length. This is why you need arrays, not pointers.
I can not find any proof that the TLV implementation above is not UB, but I saw a lot of cases where array of chars was "parsed" by casting it to pointer to some structure. I even wrote a code like this myself.
0-size arrays
As I said before, arrays of size 0 are not allowed by C standard. But they are allowed by GCC and this is handy because it allows you to do the following:
typedef struct {
unsigned char type;
unsigned char length;
unsigned char value[0];
} TLV;
int required_length = 10;
TLV *tlv = (TLV *) malloc(sizeof(TLV) + required_length);
Without 0-size arrays you'd have to add (or subtract? subtract I guess) 1 somewhere in the code above.
The following is almost entirely portable and certainly not UB due to aliasing because at no point is test dereferenced so you can forget about it.
What isn't (technically) portable is the assumption that there's no internal padding in the struct TLV.
To obtain portability I've removed the __attribute__((packed)).
If your compiler supports it then you are 100% in the clear with no UB.
That is unless you change value to an aligned type then you are likely to be broken.
This all works because sizeof(unsigned char) has to be 1 and type alignment has to divide their size. Remember, if it doesn't malloc(n*sizeof(T)) for some type T is broken as an array of n elements of type T. The C standard is painted into a corner that unsigned char can't be aligned because it's always legit to treat memory as an array of char (either kind).
So the following program will either fail at the assert(.) or execute successfully.
On all known platforms it will execute successfully as there are no known platforms that would choose to internally pad the given data structure - whether you specify packed or not.
But why do this:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef struct {
unsigned char type;
unsigned char length;
unsigned char value;
} TLV;
static TLV dummy;
int main(void) {
//There's no standard way to verify this at compile time.
//NB: If you stick with packing or leave all the members of TLV the same type
//Then this is almost certainly NOT an issue.
//However the cast of test implicitly assumes the following is the case.
//Here's a run-time check of a static constraint.
assert(offsetof(TLV,value)==(sizeof(dummy.type)+sizeof(dummy.length)));
unsigned char test[5] = {(unsigned char)'T', 0x03, 0x01, 0x02, 0x03};
TLV* tlv=(TLV*)test;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",(&tlv->value)[i]);
}
(&tlv->value)[0]=253;
(&tlv->value)[1]=254;
(&tlv->value)[2]=255;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",(&tlv->value)[i]);
}
return EXIT_SUCCESS;
}
When you can do this (C99 onwards I'm told) and have no crappy alignment problems:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
unsigned char type;
unsigned char length;
unsigned char value[];//Variable length member.
} TLV;
int main(void) {
TLV* tlv=malloc(sizeof(TLV)+3*sizeof(unsigned char));
tlv->type='T';
tlv->length=3;
tlv->value[0]=1;
tlv->value[1]=2;
tlv->value[2]=3;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",tlv->value[i]);
}
tlv->value[0]=253;
tlv->value[1]=254;
tlv->value[2]=255;
for(unsigned char i=0;i<tlv->length;++i){
printf("%u\n",tlv->value[i]);
}
free(tlv);
return EXIT_SUCCESS;
}
Notice that there is no compliant guaranteed way of allocating such things statically because there is no compliant guaranteed way of dictating the layout (and in particular size) of the structure so you cannot know how much space to allocate in the char array.
You can (of course) blend the solutions but if you pack the structure you are likely to break alignment of value (if something needing alignment) and if you don't risk the compiler internally padding TLV. That internal padding is unlikely in the current guise but actually very likely if you upgraded length to type of size_t - which is the natural 'full' answer.
The current length limit of 255 (on almost all platforms) is frankly stingy. It felt mean in 1993 writing in Turbo Pascal. In 2015 it's piffling. At least implement length as `unsigned int' unless you know such a tight ceiling is sufficient.
It's a C99 feature, called flexible array member which is typically used to create a variable length array.
It can only be specified as the last member of a struct without specifying the size (as in array_field [];).
For example, you can do the following and the member arr will have 5 bytes allocated for it:
struct flexi_example
{
int data;
char arr[];
};
struct flexi_example *obj;
obj = malloc(sizeof (struct flexi_example) + 5);
Its pros/cons discussed here:
Flexible array members in C - bad?
Such structures are usually allocated on the heap with a calculated size, with code such as the following:
#include <stddef.h>
struct test * test_new(uint32 num_fields)
{
size_t sizeBeforeArray = offsetof(struct test, array_field);
size_t sizeOfArray = num_fields * sizeof(char);
struct test * ret = malloc(sizeBeforeArray + sizeOfArray);
if(NULL != ret)
{
ret->num_fields = num_fields;
}
return ret;
}
Yes, it's called flexible array member. It's usually used with dynamically allocated objects. However, you cannot return Minefield by value. The compiler will copy only sizeof(Minefield) data what is the size of object if length of array Minefield::field was 0.
You can do:
Minefield* NewGame(int columns, int rows, int mines)
{
Cell cells[columns*rows];
...
// allocate memory for Minefield and cells array just after it
Minefield* minefield = malloc(sizeof(*minefield) + sizeof cells);
if (!minefield) { ... error handling ... }
// set normal fields using compund literal
*minefield = (Minefield){columns, rows, mines};
// copy cells `array` to `minefield->field` array
memcpy(minefield->field, cells, sizeof cells);
return minefield;
}
The memcpy can be avoided by first allocating Minefield and writing directly to field member.
Minefield* NewGame(int columns, int rows, int mines)
{
Minefield* minefield = malloc(sizeof(Minefield) + rows * columns * sizeof(Cell));
if (!minefield) { ... error handling ... }
*minefield = (Minefield){columns, rows, mines};
Cell *cells = minefield->field;
...
return minefield;
}
Unfortunately, C doesn't have any built-in dynamic array like python. However, if you want to use some dynamic array either you can implement your self or you can see the answer to that link C dynamically growing array which explains that you need to have starting array with a default size, and then you can increase the size of the array which depends on your algorithm. After you import that header file provided by @casablance, you can simply use it for your minesweeper game.
My question now is: (1) How can I iterate through this files struct pointer (Pseudocode:
for each file in files) when (2) the amount offile_ts in it is unknown at compile time and also (3) the size of eachfile_tis unknown at compile time?
Let's start from statement (3): the good news, for you, is that the size of each file_t is absolutely known at compile time. It will be the size of a char * added to the size of an integer, and you can obtain that whenever you need it with sizeof(file_t).
Not the bad new: Since statement (2) is true (the amount of file_ts in it is unknown at compile time) unfortunately the answer to (1) is: you can't. At least, you can't without modifying something.
In order to know how many items there are in your struct files_t list (that is having a way to iterate through it) you have to options:
- Add a field to
struct files_tcontaining the number of items:
struct files_t {
file_t *file;
unsigned int nrOfFiles;
};
You will take care to initialize it to 0, to increment it whenever you add a file to the list and to decrement it whenever you remove a file from it. You can iterate through it with a for loop with something like for(int i=0; i<filesList.nrOfFiles; i++).
- Design a sentinel value. A sentinel value is something meaning "this is the last element of the array". For example:
struct files_t {
file_t *file;
};
struct file_t {
unsigned char *bytes;
unsigned int len;
};
struct file_t fileArray =
{
{ charPointer0, len01 },
{ charPointer1, len1 },
/* ... */
{ charPointerN, lenN },
/* Sentinel */
{ NULL, 0 }
};
struct files_t fileList = { fileArray };
In this case you can iterate until the { NULL, 0 } element is found.
The problem is not at compile time but at execution time, almost all is always unknown at compile time.
Your alone problem concerns the unknown numbers of elements in your arrays, if you have no way to have these numbers you can mark the end of each :
- the last
file_tcan have its fieldbytesvaluing NULL. I use the pointer rather thanlento allow you to manage empty files - the last pointer in the array of
files_tcan be NULL
The latter is called a "flexible array member" which is a special case for structures. The last member of a struct is allowed to have no specified size.
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply. However, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.
Also see example 20.
The former is a normal array and it's not allowed to have zero size. See 6.7.6.2 Array declarators.
If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. In other words, the language standard says so.
In your first example, you have defined a regular array without giving its size.
This is not legal in C. Outside of a struct, your array needs a size when you declare it, as you have no way to set the size later:
int main()
{
unsigned char data[100];
return 0;
}
In your second example, you have defined a flexible array member.
This is a legal operation in C that allows you to allocate memory for the array when you allocate memory for the struct. The flexible array member must be the last element in your struct.
Here is an example, based on the one from GCC's documentation:
struct line
{
int length;
char contents[]; // Flexible array member
};
struct line *myline = malloc(sizeof(struct line) + 100); // 100 bytes for the array
myline->length = 100;
You should store a pointer in your struct:
Vertex *vertices;
Then allocate the memory at runtime:
myFile f;
f.vertices = malloc(nVertices * sizeof(Vertex));
if (f.vertices == 0)
handle_out_of_memory();
f.nVertices = nVertices;
Remember to free the memory when done:
free(f.vertices);
C99 introduces 'flexible array members', which may be what you want to use. Your code still ends up looking remarkably like the code suggested by @frast, but is subtly different.
§6.7.2.1 Structure and union specifiers
A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.
[...]
As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. With two exceptions, the flexible array member is ignored. First, the size of the structure shall be equal to the offset of the last element of an otherwise identical structure that replaces the flexible array member with an array of unspecified length.106) Second, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.
EXAMPLE Assuming that all array members are aligned the same, after the declarations:
struct s { int n; double d[]; }; struct ss { int n; double d[1]; };the three expressions:
sizeof (struct s) offsetof(struct s, d) offsetof(struct ss, d)have the same value. The structure struct s has a flexible array member d.
If sizeof (double) is 8, then after the following code is executed:
struct s *s1; struct s *s2; s1 = malloc(sizeof (struct s) + 64); s2 = malloc(sizeof (struct s) + 46);and assuming that the calls to malloc succeed, the objects pointed to by s1 and s2 behave as if the identifiers had been declared as:
struct { int n; double d[8]; } *s1; struct { int n; double d[5]; } *s2;Following the further successful assignments:
s1 = malloc(sizeof (struct s) + 10); s2 = malloc(sizeof (struct s) + 6);they then behave as if the declarations were:
struct { int n; double d[1]; } *s1, *s2;and:
double *dp; dp = &(s1->d[0]); // valid *dp = 42; // valid dp = &(s2->d[0]); // valid *dp = 42; // undefined behaviorThe assignment:
*s1 = *s2;only copies the member n and not any of the array elements. Similarly:
struct s t1 = { 0 }; // valid struct s t2 = { 2 }; // valid struct ss tt = { 1, { 4.2 }}; // valid struct s t3 = { 1, { 4.2 }}; // invalid: there is nothing for the 4.2 to initialize t1.n = 4; // valid t1.d[0] = 4.2; // undefined behavior106) The length is unspecified to allow for the fact that implementations may give array members different alignments according to their lengths.
The example is from the C99 standard.