-1
struct payload{
    struct metadata meta;
    char data_pointer[0];
};

struct payload* mypayload = (struct payload*) malloc(sizeof(struct payload) + 50);

What is the type of mypayload here? The address, pointer, or something else

FrankZZZ
  • 31
  • 2
  • The type is exactly `struct payload *`. That is, a pointer to a struct. – kaylum Apr 24 '22 at 04:26
  • It's a pointer (to struct payload). As all pointers, it contains an address in memory. The block of memory starting at this address should contain a struct payload. – wohlstad Apr 24 '22 at 04:40

3 Answers3

3

malloc returns an untyped chunk of memory, and the assignment is how you tell the compiler what type it is. In this case struct payload * which is a pointer (an address) of the memory that was allocated or NULL if the allocation failed.

You don't need the cast (struct payload*).

If you want data_pointer to be a flexible array member, then you leave the size unspecified char data_pointer[];. An array of size 0 is undefined behavior.

Allan Wind
  • 23,068
  • 5
  • 28
  • 38
1

What is the type of mypayload here?

mypayload is a pointer, a pointer to a struct payload. @kaylum


A struct array member with size 0, like char data_pointer[0]; is not defined by C although some implementations had allowed it as a pre-cursor to a flexible array member (FAM).

Since C99 use char data_pointer[]; to define the last member as a flexible array member.

To best allocate for a flexible array member, compute the sum of 2 sizes:

  • sizeof mypayload[0]: Size of the object up to, but not including the FAM member. This will include any padding before the FAM member.

  • sizeof mypayload->data_pointer[0]: Size of the FAM referenced data times the count, 50, of array elements desired.

  • Tip: a type is not needed in the sizeof code. Easier to code right, review and maintain to use the size of the referenced object.

  • Tip: Cast not needed.

  • Tip: Check for allocation success.

Example:

struct payload{
  struct metadata meta;
  char data_pointer[];  // No 0
};

struct payload* mypayload = malloc(
    sizeof mypayload[0] + 
    sizeof mypayload->data_pointer[0] * 50);
if (mypayload == NULL) {
  ; // TBD code to handle out-of-memory
} 
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • How to use the data_pointer as a dynamic array instead of using the specific 50 – FrankZZZ Apr 24 '22 at 05:35
  • @XiangfengLin Instead of `50`, use `n` like `size_t n = rand() % 100 + 1; struct payload* mypayload = malloc(sizeof mypayload[0] + sizeof mypayload.data_pointer[0] * n);`. Note: `data_pointer` is not a _dynamic array_. It is a pointer to a `struct` that has a dynamic array member. – chux - Reinstate Monica Apr 24 '22 at 05:38
  • @XiangfengLin [Comment correction](https://stackoverflow.com/questions/71985499/c-struct-type-confusing/71985701?noredirect=1#comment127199518_71985701) -- use `n` like `size_t n = rand() % 100 + 1; struct payload* mypayload = malloc(sizeof mypayload[0] + sizeof mypayload->data_pointer[0] * n);`. – chux - Reinstate Monica Apr 24 '22 at 14:02
-1

mypayload is a pointer. It's a pointer to the memory allocated by malloc(). And you have it configured as a pointer to a payload.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466