2

Possible Duplicate:
Array of zero length

I have seen such type of code :-

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct pkt {
  int pk_type;
  int tag;
  int magic_num;
  char data[0];  <-------- what does this mean ???
}__attribute__((packed));

typedef struct pkt p_t;
int main(void)
{
  p_t *p = (p_t *)calloc(1, sizeof(p_t));
  if(!p) {
    perror("p");
    return -1;
  }
  p->pk_type = 1;
  p->tag = 0xb00bbabe;
  p->magic_num = 0xcafebabe;
  strcpy("hello world", p->data); <-- Seg faults here !!!  

  return 0;

}

I was wondering the meaning of arr[0]. I mean in what scenarios do we need to use arr[0]. What purpose does it serve?

Community
  • 1
  • 1
Ashish
  • 569
  • 3
  • 10
  • 18
  • This will seg fault even if array was defined to be of enough size - you're copying from `p->data` to a string literal. – Amarghosh Aug 31 '10 at 09:50
  • Just a quick note: C++ doesn't allow zero-length arrays statically. – Puppy Aug 31 '10 at 09:50
  • 1
    @DeadMG: Neither C not C++ allows zero-length arrays anywhere at all. Zero-length array declarations are always explicitly illegal. – AnT stands with Russia Aug 31 '10 at 10:04
  • @Andrey..This URL talks about zero lenge array http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Zero-Length.html#Zero-Length – Anil Vishnoi Aug 31 '10 at 10:09
  • @Anil Vishnoi: What do you expect me to find at that URL? – AnT stands with Russia Aug 31 '10 at 10:10
  • @Andrey That _Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure which is really a header for a variable-length object:_ – Amarghosh Aug 31 '10 at 10:16
  • @Amarghosh: That's great, but I don't see the relevance. Firstly, the question is about C, since it is tagged [C]. Secondly, the same thing can be implemented legally by declaring the array with size 1 or *any* other *legal* size. So, useful or not, zero-sized array declarations are *illegal* in C. In fact, the URL clearly states that in C90 you have to use size 1 and in C99 you have to use the `[]` declaration, since the `[0]` is illegal. – AnT stands with Russia Aug 31 '10 at 10:19
  • The only "useful" thing about it is that it allows using `sizeof` for calculating the total size, as shown at that URL. The reality though is that declaring arrays with `[0]` just to allow such a `sizeof` use is a bad programming practice. There are better, array-size independent ways to do it (using `offsetof`, for example), but the rather bad-quality article at the URL fails to mention it. – AnT stands with Russia Aug 31 '10 at 10:23

5 Answers5

7

In C, the members of a struct are always allocated in the order they appear. So, my_pkt->data is a pointer "one past the end" of a pkt object. If initialized with

my_pkt = malloc( sizeof( struct pkt ) + 50 );

then my_pkt->data points to the beginning of a 50-byte general-purpose buffer.

Only the final member of a struct is allowed to be defined this way.

To be more compliant with C99, omit the 0 and write char data[];.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • It's not necessarily "one past the end" -- there might be struct padding. – Philip Potter Aug 31 '10 at 09:58
  • 2
    Firstly, zero-size array declarations are illegal in all versions of C language. Secondly, `my_pkt->data` is not really a pointer. – AnT stands with Russia Aug 31 '10 at 10:02
  • @AndreyT: do you have a reference for zero-size arrays being illegal (presumably, a constraint violation)? what about VLAs where the size happens to be zero? I can't find anything in n1256. – Philip Potter Aug 31 '10 at 10:08
  • @Philip Potter: VLAs can indeed have zero size. I was talking about compile-time-sized declarations. The requirement is given in 6.7.5.2/5 of C99: "... it shall have a value greater than zero". The same requirement is present in 6.5.4.2 in C89/90: "... shall be an integral constant expression that has a value greater than zero". – AnT stands with Russia Aug 31 '10 at 10:15
  • @AndreyT: actually, 6.7.5.2/5 talks about non-integer constant expressions, so VLAs must be size >0 too. (I now see 6.7.5.2/1 places a constraint on non-VLA array size >0). – Philip Potter Aug 31 '10 at 10:30
  • @Philip Potter: You are right. The proper reference for compile-time-sized arrays is 6.7.5.2/1 in C99: "If the expression is a constant expression, it shall have a value greater than zero". And indeed even VLAs can't have zero size (somehow I thought they could). – AnT stands with Russia Aug 31 '10 at 10:36
  • No, it's not a pointer variable in that it cannot be reassigned to point somewhere else. But neither is it really an array, since it is defined to have zero size. See the link in deus-ex's answer. – Potatoswatter Aug 31 '10 at 18:51
0

It's a flexible array member, that can be used, when you need a structure of varying size. It simplifies the allocation of the extra size, just see the link.

DerKuchen
  • 1,840
  • 1
  • 15
  • 15
0

This is what the GCC Manual has to say about zero length arrays

doron
  • 27,972
  • 12
  • 65
  • 103
0

This is a zero byte array. Used to append data of arbitrary size at runtime. Very useful in sending data over a socket.

You should refer this for more details- http://bytes.com/topic/c/answers/547407-char-data-0-a

Sandeep Pathak
  • 10,567
  • 8
  • 45
  • 57
-1

char arr[0] is a same as char *. And the reason you are getting segmentation fault is,because when you do calloc in following line of code

p_t *p = (p_t *)calloc(1, sizeof(p_t));

it actually initialize every memory with zero.So when you passed a null pointer,it caused segmentation fault because of null pointer.

Anil Vishnoi
  • 1,352
  • 3
  • 18
  • 25