tags:

views:

95

answers:

5

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?

+3  A: 

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
It's not necessarily "one past the end" -- there might be struct padding.
Philip Potter
Firstly, zero-size array declarations are illegal in all versions of C language. Secondly, `my_pkt->data` is not really a pointer.
AndreyT
@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
@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".
AndreyT
@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
@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).
AndreyT
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
A: 

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
A: 

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
Array (even of a zero size) is not a pointer. So, no, it is not even remotely the same as `char *`.
AndreyT
A: 

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

doron
A: 

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