INFO: Using a Structure with an Empty Array Member

This article was previously published under Q98409
This article has been archived. It is offered "as is" and will no longer be updated.
Summary
The information below is derived from the Microsoft C/C++ version 7.0online help file. To view the topic that corresponds to this article,search for the word "struct" and choose the "Unsized Arrays inStructures" topic.

In the C language, an application can define structure that containsan unsized array as one of its fields. However, an application cannotdefine an array of structures when the structure contains an unsizedarray because the structure declaration does not allocate any memoryfor the unsized array.
More information

Background

The following structure declaration includes an unsized array field:
struct test{   int x, y, z;   char empty[];}				
The code example below demonstrates how the compiler processes thestructure declaration. The sizeof macro returns the size of thestructure, but does not include the unsized array. For the structuresample above, the sizeof macro returns the value of 6 bytes for the16-bit compiler and 12 bytes for the 32-bit compiler.

Declaring Structures with Unsized Array Fields

An application can declare an instance of a structure type thatincludes an unsized array field, but the behavior of the compiler isunpredictable.
   struct test x;				
In the declaration above, the compiler allocates six bytes for x andthe address of the empty field is set to six bytes beyond the addressof x. This may present a problem because empty is a character array.If the application interprets empty as a string, the string has nolength and ends only when a null terminating character (zero value)appears in memory.

An attempt to create an array of structures (for example, with astruct text x[10] declaration) fails and the compiler generates thefollowing messages:
warning C4001: nonstandard extension 'zero sized array in struct/union' was used

error C2087: 'x' : missing subscript
The compiler that is included with Visual C++ versions 5.0 and 6.0 generates the following error:
error C2233: '<Unknown>' : arrays of objects containing zero-size arrays are illegal
An application can initialize an instance of a type that contains anunsized array field using the following syntax:
   struct test x={1, 2, 3, "Test String");				
In this example the empty field in x points to the 'T' in "TestString" and the string is correctly terminated with a null terminatingcharacter after the 'g'.

An application can declare a pointer to a structure that contains anunsized array field. The application must allocate memory for to storethe contents of the array. Given the structure declaration above, thefollowing code declares a pointer to structure and allocates memory tostore an instance of the structure:
   struct test *right;   right = malloc(sizeof(struct test) + stringlength + 1);				
The stringlength variable contains the length of the string stored inthe structure and the constant 1 provides space to store theterminating null character. Even though the application allocatesmemory to store the string, the sizeof macro returns the size of theelements in the structure except for the unsized array element.

Using this technique, an application can use malloc() to declare an arrayof structures that contain unsized array fields; however, the applicationmust correctly calculate the proper amount of memory to allocate to storethe structures and the strings and it must correctly implement pointers toaccess elements of the array. Because the size of the structure does notinclude the storage required by the unsized array element, the value(ptr+1) points to the sixth (or twelfth) byte of the allocated array whichis not necessarily the first field of the second element.

An attempt to allocate an array of structures produces the C4001 warningdescribed above. The C2087 error does not occur because the size of thearray is not specified.

Sample Code

/* * Compile options needed: /W4 */ #include <stdio.h>struct test{   int x, y, z;   char str[];};struct test trythis;void main(void){   printf("the size of test is %d bytes\n",sizeof(struct test));}/* Output */ /* 16-bit compiler output */ the size of test is 6 bytes/* 32-bit compiler output */ the size of test is 12 bytes				
8.00 8.00c
Properties

Article ID: 98409 - Last Review: 10/26/2013 02:58:00 - Revision: 3.0

  • Microsoft Visual C++ 2.1
  • Microsoft Visual C++ 4.0 Standard Edition
  • Microsoft Visual C++ 1.0 Professional Edition
  • Microsoft Visual C++ 1.52 Professional Edition
  • kbnosurvey kbarchive kbcode kbcompiler kbinfo KB98409
Feedback