6

I'm trying to create an array of structs and also a pointer to that array. I don't know how large the array is going to be, so it should be dynamic. My struct would look something like this:

typedef struct _stats_t
{
 int hours[24]; int numPostsInHour;
 int days[7]; int numPostsInDay;
 int weeks[20]; int numPostsInWeek;
 int totNumLinesInPosts;
 int numPostsAnalyzed;

} stats_t;

... and I need to have multiple of these structs for each file (unknown amount) that I will analyze. I'm not sure how to do this. I don't like the following approach because of the limit of the size of the array:

# define MAX 10
typedef struct _stats_t
{
 int hours[24]; int numPostsInHour;
 int days[7]; int numPostsInDay;
 int weeks[20]; int numPostsInWeek;
 int totNumLinesInPosts;
 int numPostsAnalyzed;

} stats_t[MAX];

So how would I create this array? Also, would a pointer to this array would look something this?

stats_t stats[];
stats_t *statsPtr = &stats[0];
2
  • 1
    Questions: Can you manage a dynamic array of int? Can you manage a static array of struct? If there answer to either of these questions is "No.", I'd suggest working on that first. Once you can manage both of those, the answer to this should be obvious. Finally, you can find help on both of the above on Stack Overflow already. Commented Apr 4, 2010 at 21:19
  • 1
    The _t suffix is reserved for system headers. Don't use it. Commented Apr 20, 2018 at 9:24

5 Answers 5

6

This is how it is usually done:

size_t n = <number of elements needed>
stats_t *ptr = malloc (n * sizeof (stats_t));

Then, to fill it in,

for (size_t j = 0;  j < n;  ++j)
{
   ptr [j] .hours = whatever
   ptr [j] .days = whatever
   ...
}
Sign up to request clarification or add additional context in comments.

5 Comments

a) You should use size_t instead of int. int is a signed type, and we rarely want to allocate an array with -1 length. b) I would use sizeof *ptr instead of sizeof(stats_t), but it doesn't matter here.
Thank you for your responses. I understand how to allocate the memory and access it, but the problem is that I will malloc one struct at a time. Everytime a new file comes along, I will malloc another struct for it. So I can't malloc 'n' structs and then go back and do work on it, rather I need to say "Here's the array, expand (add to it) once every time a new file comes along." Does that make sense?
@Hristo: For that, use the realloc() function to resize an array allocated with malloc(). That's why it's called dynamic allocation.
ahh... thanks. That is what I was looking for. Now I just need to learn how it works and the syntax.
Using realloc each time the array grows is very inefficient. Better is double the array size each time. You'll need to keep track of how many are allocated separately from how many are used though. Another solution is to use a TAILQ or similar. Edit: sorry this is really old, didn't see that.
2

The second option of a pointer is good.

If you want to allocate things dynamically, then try:

stats_t* theStatsPointer = (stats_t*) malloc( MAX * sizeof(stats_t) );

as Roland suggests.

Just don't forget to

free(theStatsPointer);

when you're done.

4 Comments

the problem is i don't know MAX right away... I don't know how many files I'll have to deal with so setting a MAX would be a bad idea.
I don't want to repeat myself, but since your code is almost identical to sblom's (other than the correct declaration of theStatsPointer), see point b) in my comment there. But +1 for reminding us to free().
@Chris: I didn't see sblorn's until after I posted. At the time I posted, I only saw Roland's post.
@Hristo: MAX does not have to be a constant. If you really must, you can always use realloc() if you exceed the already existing block of memory (of size MAX stats_t structs). D'oh! Just saw Chris Lutz's comment mentioning it too.... sorry for the dupe, Chris! ;-)
0

Use malloc():

http://en.wikipedia.org/wiki/Malloc

Comments

0

malloc is your friend here.

stats_t stats[] = (stats_t*)malloc(N * sizeof(stats_t));

stats sort of is a pointer to the array. Or you can use stats[3] syntax as if it were declared explicitly as an array.

5 Comments

the problem is i don't know 'n' right away... I don't know how many files I'll have to deal with.
a) You can't declare something like stats_t stats[]. That's an array with no size, not a pointer. You need stats_t *stats. b) I highly recommend against casting the return value of malloc() in C code, and the use of sizeof(stats_t), both of which make changing the type of stats more complicated. The cast also has other, less justified stigmas associated with it.
What would you recommend instead of sizeof?
sizeof. :P I prefer the use of sizeof *ptr over sizeof(type) because if the type of ptr changes, sizeof *ptr adjusts automatically to the correct size, while sizeof(type) must be manually changed and is therefore more error prone. In this case, it doesn't matter because I doubt the type of stats will change, but in other cases it can be helpful.
@ChrisLutz Ironically, I just used your suggestion for the first time in my C code, and then within 60 seconds had to rename the variable, and so had to change the sizeof parameter too!
0

Based on your replies to other answers it looks like you need a dynamic data structure like a linked list. Take a look at the queue(3) set of facilities.

3 Comments

The queue(3) functions aren't standard.
What C data structure library is standard?
The only C data structures that are "standard" (when "standard" means ISO C99) are pointer, array, struct and union. ISO C99 doesn't know anything about lists, sets, maps, trees, whatever. You have to use an external library for all these things.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.