Declaring a zero sizes array [duplicate] - c

This question already has answers here:
zero length arrays [duplicate]
(3 answers)
Closed 9 years ago.
I tried declaring an array a of size 0:
int a[0];
My VC++ 6 compiler throws an error of not being able to create an array of zero size.
If I try the same of declaring inside a structure, I do not get any errors.
struct st
{
int a[0];
}
The code gets compiled and linked without any errors. Can somebody help me understand how the compiler reacts in the above two cases. Thanks.

The struct is a special case. It is a common pattern to declare an empty array as the last member of a struct, where the struct is actually part of a larger block of memory of variable length. See Empty arrays in structs for more explanation.

Some compilers support the extension of using zero-sized arrays as the last element of the struct, to indicate your intent to allocate there an array whose size you don't know yet. Then you can use that struct member (the zero-sized array) to access the elements of that array.
Note that is not an standard feature from C89, and C99 offers an alternative solution:
struct st
{
int a[];
}

Related

C, use int variable as array size inside structure [duplicate]

This question already has answers here:
Can we have a struct element of type Variable length array? [duplicate]
(5 answers)
Closed 2 years ago.
I would like to define array size inside a structure by using a parameter of this structure. Does C permit to do something like this ?
struct queue {
int head;
int top;
int size;
struct action action[size];
};
No you can't. Since action is not a dynamic variable, the compiler needs to know at compile time how much space it needs for action. size was not even initialized. Anyway, you could see this just by trying to compile.
The size is not known at the time of defining the struct. Therefore it is impossible for the compiler to understand how large the result will be. Typically, you would first allocate memory for the struct, and have a struct action *action; member. After initializing the struct, you use instance->action = calloc(instance->size, sizeof *instance->action) to allocate memory for the array.

Dynamically declaring structs not working as expected [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 5 years ago.
I'm having issues with my program, and I'm trying to break it down and I'm seeing that I'm having issues with memory allocation at a minimum.
I have a struct:
typedef struct{
int originX;
int originY;
char ticBoard[3][3];
int result;
int turn;
} simBoard;
I would expect the size of this struct (one single instance of it) to be (4 ints * 4 bytes) + (1 bye char * 3 * 3) or 25 bytes. When I run the sizeof() function on simBoard, I get a value of 28 bytes. I'm assuming that it's the 25 + 3 extra that I don't need to worry about.
The main issue is when I try to declare an array of this struct
simBoard* boardArray = (simBoard*)malloc(sizeof(simBoard)*size));
Assume size is some constant for this scenario. To my knowledge this should create an array of the simBoard struct, of size size. I should be able to go
boardArray[3]
And get the 4th item of boardArray correct? However I'm running into an issue with the memory allocation. When I run:
printf("%zu is the size of the array\n", sizeof(boardArray));
The return value is 8. I even tried to further sort out the issue:
simBoard* boardArray = (simBoard*)malloc(224);
When I ran the printf again, I'm still getting a value of 8 bytes for boardArray. If you guys could lead me in the right direction that'd be fantastic, as I'm absolutely stumped here.
Thank you!
You can indeed index the 4th struct in the array using the notation boardArray[3].
Bear in mind though that boardArray itself is a pointer type. That explains your printf output. Arrays with dynamic storage duration and pointer types are inextricably linked in C. For the avoidance of doubt, sizeof(boardArray) is sizeof(simBoard*).
C doesn't provide functionality to obtain the length of an dynamic array. You need to remember the length yourself.
Don't forget to call free(boardArray) when your done. The C runtime library will take appropriate measures to ensure that all the struct elements are freed.

C Array as function parameter: Size check? [duplicate]

This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 7 years ago.
I wrote the following function in C:
void dummy(int* my_array, int size)
{
//my implementation
}
Is there any way to check whether size is REALLY the size of my_array?
For example, if I call the function and use for my_array an array with 4 elements but pass 5 for size, is there any way to know that 5 is not really the size of the array?
Thank you in evidence.
You're looking at it the wrong way. An array is contiguous piece of memory. In C, you can represent this concept with a pointer to its start and its size. Since your array is represented by a <my_array, size> tuple, it doesn't make sense to talk about my_array's size, since it's only the start-pointer of the array.
unfortunately, there is no such way in C. As an array is always a pointer to an arbitrary address in memory, there is no such thing as "array bounds" that can be checked.
This is why many of the C functions have that special size parameter: because there's no other way of determining an array's size.
The size of the array is however big you made it when you declared and initialized it.
int my_array[100] = {0}; has a size of 100.
int my_other_array[50] = {0}; has a size of 50.
If you want the length of the data, then you're thinking in more abstract terms than the language can handle. The length of your data is a non-measurable parameter when the language does not support it.
If my_array is dynamically allocated (with malloc) you can get the size of memory block but it depends on specific compiler. Unfortunately in most cases there is address alignments and you will not have the exact size to 1 byte but aligned to 32 bits or other.

Is this use of an array Undefined Behavior? [duplicate]

This question already has answers here:
Is the "struct hack" technically undefined behavior?
(8 answers)
Closed 7 years ago.
In a solution I posted I got comments that the solution contains Undefined Behavior. However, I do not see how. The basic of the solution posted is:
typedef struct {
int n;
int a[1];
} t_x;
void example(void)
{
int i;
t_x *t= malloc (sizeof(t_x) + 99*sizeof(int));
t->n= 100;
for (i=0; i < t->n; i++)
t->a[i]= i;
free(t);
}
The comment of UB centered on whether the array now has 1 element (as declared) or has 100 elements (as allocated).
The parts of the standard quoted were 6.5.6 (pointer/int addition) and 6.5.2.1 (array subscripting)
"6.5.6 defines what happens when you add a pointer and an integer. The resulting pointer points to a corresponding element of the array, if such an element exists, or to one element past the end. The result is undefined otherwise."
"6.5.2.1 defines what a[n] means in terms of a+n. It follows that you cannot say a[n] if a doesn't have at least n+1 elements."
With both quotes the commenter seems to imply that element a[99] would not exist, however, looking at the memory lay-out it clearly exists:
Please help me understand if/why this is UB and what types of UB I may expect.
This is a pretty popular trick in pre-C99 code. It works in many implementations, but is not strictly speaking legal (thus not portable). The standard doesn't say how the strcture of t_x aligns in memory. See C FAQ for detail.
C99 introduced flexible length array, which is preferred for such problem.
Ok, so the problem is, that you want to allocate memory for a table, that you defined in code. This table will always be of size one as you written, so you can store one object of type int in there.
If you want to allocate memory dynamically for a, then you should:
typedef struct {
int n;
int* a;
} t_x;
and then
t_x someStruct;
someStruct.a=(int*)malloc(numberOfElements*sizeof(int));

Flexible Array Member (Zero Length Array) [duplicate]

This question already has answers here:
Array of zero length
(5 answers)
Closed 8 years ago.
In reference to GCC's Zero Length Array explanation:
This is particularly useful in the case when a struct is a header for a variable-length object. This is exactly my case. Furthermore, I am concerned with the alignment of my structs in the heap.
In this case, I still really do not understand what's useful about zero length arrays. How are they related to this particular situation?
EDIT:
Is it that I can put as much "data" as I want in there?
Basically it allows you to have a structure with a variable length array at the end:
struct X {
int first;
int rest[0];
};
An array size of 0 is not actually valid (although it is allowed as a gcc extension). Having an unspecified size is the correct way.
Since C doesn't really care that you are accessing elements beyond the end of the array, you just start with an undefined array size, and then allocate enough memory to handle however many elements you actually want:
struct X *xp = (struct X *)malloc(sizeof(struct X)+10*sizeof(int));
xp->rest[9] = 0;
The memory returned from malloc() that you will assign to a pointer to the struct with the zero-length array member will be aligned memory ... that's required by the C99 specification. So there is no issue overlaying a struct with a zero-length array over memory allocated from the heap via malloc().
Where you would run into trouble would be attempting to overlay your struct over some raw buffer in memory that came from a packed or non-traditionally aligned data-source, such as a file-header, memory-mapped hardware interface, etc. In those cases, using a zero-length array to handle the variable-length data can be a bad idea since the data may not be aligned according to the default alignment parameters of the platform, and thus offsetting into the array will not yield the correct results.

Resources