-4

I am having an issue creating a dynamic array of structures. I have seen and tried to implement a few examples on here and other sites, the examples as well as how they allocate memory tend to differ, and I can't seem to get any of them to work for me. Any help would be greatly appreciated.

typedef struct node {
    int index;
    int xmin, xmax, ymin, ymax;
} partition;

partition* part1 = (partition *)malloc(sizeof(partition) * 50);

I can't even get this right. It gives me the following error: error: initializer element is not constant

If anyone could explain how something like this should be implemented I would greatly appreciate it.

Also, once I have that part down, how would I add values into the elements of the structure? Would something like the below work?

part1[i]->index = x;
econsteve
  • 55
  • 1
  • 1
  • 4
  • 1
    Please post a complete source code for your example program. – code_dredd Oct 27 '15 at 02:05
  • post the code, i have mad simple program that uses this struct and all you posted and it works. –  Oct 27 '15 at 02:08
  • [This](https://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w) SO post seems related to your error message – code_dredd Oct 27 '15 at 02:08
  • 1
    If the call to `malloc` is outside of a function, then *that's* the problem for the first – code_dredd Oct 27 '15 at 02:11

1 Answers1

2

The compiler is complaining because you're doing:

partition* part1 = (partition *)malloc(sizeof(partition) * 50);

Do this instead:

partition* part1;

int
main(void)
{

    part1 = (partition *)malloc(sizeof(partition) * 50);

    ...
}

Your version used an initializer on a global, which in C must be a constant value. By moving the malloc into a function, you are "initializing the value" with your code, but you aren't using an initializer as defined in the language.

Likewise, you could have had a global that was initialized:

int twenty_two = 22;

Here 22 is a constant and thus allowable.

UPDATE: Here's a somewhat lengthy example that will show most of the possible ways:

#define PARTMAX     50
partition static_partlist[PARTMAX];
partition *dynamic_partlist;

int grown_partmax;
partition *grown_partlist;

void
iterate_byindex_static_length(partition *partlist)
{
    int idx;

    for (idx = 0;  idx < PARTMAX;  ++idx)
        do_something(&partlist[idx]);
}

void
iterate_byptr_static_length(partition *partlist)
{
    partition *cur;
    partition *end;

    // these are all equivalent:
    //   end = partlist + PARTMAX;
    //   end = &partlist[PARTMAX];
    end = partlist + PARTMAX;

    for (cur = partlist;  cur < end;  ++cur)
        do_something(cur);
}

void
iterate_byindex_dynamic_length(partition *partlist,int partmax)
{
    int idx;

    for (idx = 0;  idx < partmax;  ++idx)
        do_something(&partlist[idx]);
}

void
iterate_byptr_dynamic_length(partition *partlist,int partmax)
{
    partition *cur;
    partition *end;

    // these are all equivalent:
    //   end = partlist + partmax;
    //   end = &partlist[partmax];
    end = partlist + partmax;

    for (cur = partlist;  cur < end;  ++cur)
        do_something(cur);
}

int
main(void)
{
    partition *part;

    dynamic_partlist = malloc(sizeof(partition) * PARTMAX);

    // these are all the same
    iterate_byindex_static_length(dynamic_partlist);
    iterate_byindex_static_length(dynamic_partlist + 0);
    iterate_byindex_static_length(&dynamic_partlist[0]);

    // as are these
    iterate_byptr_static_length(static_partlist);
    iterate_byptr_static_length(static_partlist + 0);
    iterate_byptr_static_length(&static_partlist[0]);

    // still the same ...
    iterate_byindex_dynamic_length(dynamic_partlist,PARTMAX);
    iterate_byindex_dynamic_length(dynamic_partlist + 0,PARTMAX);
    iterate_byindex_dynamic_length(&dynamic_partlist[0],PARTMAX);

    // yet again the same ...
    iterate_byptr_dynamic_length(static_partlist,PARTMAX);
    iterate_byptr_dynamic_length(static_partlist + 0,PARTMAX);
    iterate_byptr_dynamic_length(&static_partlist[0],PARTMAX);

    // let's grow an array dynamically and fill it ...
    for (idx = 0;  idx < 10;  ++idx) {
        // grow the list -- Note that realloc is smart enough to handle
        // the fact that grown_partlist is NULL on the first time through
        ++grown_partmax;
        grown_partlist = realloc(grown_partlist,
            grown_partmax * sizeof(partition));

        part = &grown_partlist[grown_partmax - 1];

        // fill in part with whatever data ...
    }

    // once again, still the same
    iterate_byindex_dynamic_length(grown_partlist,grown_partmax);
    iterate_byindex_dynamic_length(grown_partlist + 0,grown_partmax);
    iterate_byindex_dynamic_length(&grown_partlist[0],grown_partmax);

    // sheesh, do things ever change? :-)
    iterate_byptr_dynamic_length(grown_partlist,grown_partmax);
    iterate_byptr_dynamic_length(grown_partlist + 0,grown_partmax);
    iterate_byptr_dynamic_length(&grown_partlist[0],grown_partmax);
}

There are two basic ways to interate through an array: by index and by pointer. It does not matter how the array was defined (e.g. global/static --> int myary[37]; or via malloc/realloc --> int *myptr = malloc(sizeof(int) * 37);). The "by index" syntax and "by pointer" syntaxes are interchangeable. If you wanted the 12th element, the following are all equivalent:

myary[12]
*(myary + 12)
*(&myary[12])

myptr[12]
*(myptr + 12)
*(&myptr[12])

That's why all of the above will produce the same results.

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • 1
    Just posting a "try this" response with no explanation to the OP as to what his misunderstanding is does not look as useful. Please consider updating your post. – code_dredd Oct 27 '15 at 02:12
  • This took care of the error. Thank you. I still don't really understand how to use this array of structures though. Specifically in relation to the last part of my post. Not sure how to specify which structure within the array I want to fill in the elements for. Something like part1[i]->index = x; does not work. Any ideas? – econsteve Oct 27 '15 at 02:21
  • @econsteve As long as `i` is within bounds, doing `part1[i]->index = x` is completely legal. Can you elaborate the "does not work" part? – harshad shirwadkar Oct 27 '15 at 03:02