Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
338 views
in Technique[技术] by (71.8m points)

c - Issue implementing dynamic array of structures

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;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...