4

I've been reading about this for a while and I'm not sure I have found a good answer.

I'm trying to setup an array of 92 structs. It's a fixed length and will not change as it's effectively a lookup table. I thought that the best way to do this was to first allocate the memory with calloc and then load the data.

But after some reading I see a lot of people allocating the memory directly without calloc or malloc like this

 myStruct myData[92] = { {1,2}, {3,4}, ....};

My first question is whether it is better to dynamically allocate the memory? My understanding was that this was a better solution. Especially if the data is not necessarily going to be used all the time.

My second question is in regards to initialising the data. I had read that I can initialise a struct using ... = {....}; but the compiler is not accepting that.

Here is the code I have so far:

typedef struct {
    int a;
    int b;
} myStruct;

@implementation MyClass

    static myStruct *myData;

    -(id) init {
         // ...

         myData = (myStruct *) calloc(92, sizeof(myStruct));
         myData[0] = {1,2}; // <=== Error ! Compiler says "Expected expression!"

         // ...
Kaa
  • 677
  • 6
  • 17
drekka
  • 20,957
  • 14
  • 79
  • 135
  • 2
    myData[0]=... is an assignment, not initialization. Unfortunately, initialization syntax isn't allowed for assignment. – Vaughn Cato Mar 18 '12 at 04:06
  • 2
    Why use dynamic allocation when static allocation is possible? `static myStruct myData[92]` –  Mar 18 '12 at 04:09
  • 1
    Thats one of the things I am trying to understand. I presume it's better to do dynamic for unknown things where as static is for fixed. So My initial code which was dynamic should be static, even though it's (relatively speaking) large? – drekka Mar 18 '12 at 04:11

3 Answers3

5

Your code looks like Objective-C, is that correct?

If you know how many elements are in an array (and it is a sane processor and operating system), it is always simpler to explicitly define it.

Whenever you dynamically allocate an array, you need to protect against something going wrong, which makes the code harder to understand.

If it is really a lookup table, and all of the values are known at compile time, you can just initialise it:

struct {
    int a;
    int b;
} myStructDate[92] = { {1, 2}, {3, 4}, ... {181, 182}, {183, 184} };
gbulmer
  • 4,210
  • 18
  • 20
  • 1
    And, if the values are constant, mark the whole array `const` and it will likely be added to the read-only 'text' section of the program. – Jonathan Leffler Mar 18 '12 at 05:24
3

About question 1: statically allocating the array should be just fine. The array will be stored in your binary's data section, will be loaded into the process's virtual memory, and swaped out by the OS if necessary, just like any other piece of memory your process is using. It will also save time when accessing the data, since you don't need to allocate and initialize it.

About question 2: gcc at least doesn't like initializing array elements like that. But you can cheat using a temp variable:

myStruct s = {1,2};
myData[0] = s;

I'm not really sure what the standard says regarding this.

vanza
  • 9,715
  • 2
  • 31
  • 34
2

Because this is not initialization you will need to do assignment

myData[0].a = 1;
myData[0].b = 2;

You can use the {} initialization when you are initializing it like this example, which also sets your array. This is a little wasteful since you don't need the temp variable if you use the above method.

myStruct temp = {1,2};
myStruct* myData = (myStruct *) calloc(92, sizeof(myStruct));
myData[0] = temp;

A good rule of thumb about when to allocate memory on the heap (via malloc/calloc) is if you need to use it outside of the function. Otherwise you should probably do it on the stack (with local variables).

Michael Chinen
  • 17,737
  • 5
  • 33
  • 45