0

So I am attempting to modify some code and I need to create an array of a struct. The struct is declared as follows:

typedef struct header
{
    int sample_rate;
    int num_channels;
    int bit_res;
    int num_samples;
    char *data;
} header;

typedef struct header* header_p;

What is the correct way to create and use an array of this struct? I was attempting something along the lines of:

header_p fileHeader;
...
fileHeader = (header_p)malloc(sizeof(header) * (argc-1));

Which seems to work but I am not sure how to access the array correctly.

EDIT: (Some of my question somehow got chopped off) When I try to access the array like so:

fileHeader[0] = function that returns header_p;

I get the following compile error:

incompatible types when assigning to type ‘struct header’ from type ‘header_p’

EDIT: (Figured this out) After following Lundins advice to remove the silly typedef hiding the struct pointer it became much easier to see what was going on. It was then easier to see that Alex was right about the need to dereference my pointer. I am going to accept Alex's answer since technically that was my issue.

tgai
  • 1,117
  • 2
  • 14
  • 29

3 Answers3

2

What is the correct way to create and use an array of this struct?

header* fileHeader;

fileHeader = malloc(sizeof(header) * (argc-1));
  • The pointer typedef doesn't make sense and makes your program unreadable.
  • Casting the result of malloc doesn't make sense.
  • You allocated sizeof(header) * the number of arguments and then -1 byte and not -1 argument as intended. Watch operator precedence. This is a bug, you are allocating too much memory.
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • So everything you said makes sense but I am still unable to access the array. I am still getting the same compile error I mentioned in my question. – tgai Mar 21 '13 at 07:42
  • @Tarmon The compiler error is related to the superfluous pointer typedef that doesn't make any sense. If you remove it, you will likely remove your problems as well. _Never_ hide pointers behind typedefs, it is very poor style. – Lundin Mar 21 '13 at 07:46
  • Alright, in all honesty I am was a little confused about the typedef but I borrowed some code and it worked so I just went with it. I will go back and try to clean that up and see if my life is any easier. – tgai Mar 21 '13 at 07:48
  • Thanks for your help, wish I could accept both of these answers! – tgai Mar 21 '13 at 08:06
1

Here:

fileHeader[0] = function that returns header_p;

You forgot pointer dereference.

fileHeader[0] = *function_returning_header_p();
Alex
  • 9,891
  • 11
  • 53
  • 87
  • Cast to `(header_p)` is unnecessary. – Tushar Mar 21 '13 at 07:38
  • @Tushar, `malloc()` returns `void*`. – Alex Mar 21 '13 at 07:38
  • Correct, but see: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Tushar Mar 21 '13 at 07:40
  • @Lundin, @Tushar Ok, yes it is not necessary, but personally for me it is the same as `NULL == ptr` style. If you forgot to include something or you're make an assignment instead of comparison, this is your problem. Anyway, question is not about casting. – Alex Mar 21 '13 at 07:46
  • @Alex That doesn't even make sense! Are you then consistently writing code like this as well? `len = (int)strlen()`, `str = (char*)strstr()`, `my_double = (double)sin()`. You don't? Then why is your coding style completely inconsistent? – Lundin Mar 21 '13 at 07:54
  • @Lundin It is not the same. `char * strstr (char * str1, const char * str2);`, `double sin (double x)` and `size_t strlen ( const char * str );` but `void* malloc (size_t size);` – Alex Mar 21 '13 at 08:00
  • @Alex You were correct about the pointer dereference but the argc was kind of a hackish work around I was using for the time being. I replaced it with 'n' in my question since it has nothing to do with my issue. – tgai Mar 21 '13 at 08:01
  • @Alex Ok bad example. How about `memcpy(a, b, n)` where a and b are pointers and n is an int. Do you always write it as `(void) memcpy( (void* restrict)a, (const void* restrict)b, (size_t)n) );`? Why not? – Lundin Mar 21 '13 at 10:43
  • @Lundin No, I don't. I just say the reasons that are written here http://c-faq.com/malloc/mallocnocast.html do not seem to me really good. If you want to discuss it the Lounge is opened in chat. BTW, comments are not place for discussions. – Alex Mar 21 '13 at 11:31
  • @Alex Plenty of discussion [here](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) and [here](http://stackoverflow.com/questions/1565496/specifically-whats-dangerous-about-casting-the-result-of-malloc). – Lundin Mar 21 '13 at 11:45
  • @Lundin If it will make you happy, so OK YOU'RE RIGHT. This casting is not necessary as I said in my second comment to this answer. It's kind of holywar don't you think? – Alex Mar 21 '13 at 12:01
0

You can access it like this:

fileHeader[0].bit_res     = ...
fileHeader[1].num_samples = ...

Since it's an pointer, you deference it at an index with the []. Then you access the members with the ..

Kyurem
  • 1,839
  • 1
  • 13
  • 7