简体   繁体   中英

How can I declare and unpack an array of pairs of void pointers?

I would like to write a function that takes an array of void* "pairs" - each one is a pair of pointers to something. The first element in each pair will be a string, and the second will be a pointer to something else.

I would like the array passed into the function to be declared like so:

<what type?> argument = {
        { "some string", <some pointer>},
        { "some other string", <some other pointer>},
        // ... etc
        NULL // To signal ending
}

function(argument);

Inside function , I would like to iterate over the array, access each "pair", cast the members of the "pair" to their respective types (known to me) and make use of these members.

I'm having some trouble with this. At first, I tried declaring the argument as void* thing[][] . Thinking it's an array of arrays of void pointers.

However, simply trying to access an index in such an array gives me the error: expression must be a pointer to a complete object type .

Reading on SO I realized the compiler is thinking I'm trying to dereference a void* . But I thought that doing a[0] on such an array would access the first "pair" in the array, which should be dereferencing a void** - which is legal. Am I wrong?

What is the correct approach to go about this, in terms of the type of the array, it's initialization and the way to unpack the array during iteration?

You want void *argument[][2] = { /*... */ }; . You have an array of unspecified size, whose elements are arrays of fixed size 2, whose elements are pointers to void . Your original compiler error was because when you have multiple square braces, only the first set of them can be empty, so adding the 2 fixed it.

By the way, it can decay as a pointer, in which case it would be void *(*argument)[2] .

Note that your sentinel NULL doesn't do quite what you'd expect, since it's in an array of arrays, and arrays aren't quite pointers. Note this warning:

warning: suggest braces around initialization of subobject [-Wmissing-braces]
        NULL // To signal ending
        ^~~~
        {   }

Here's a sample program that uses the type:

#include <stdio.h>

void *g[][2] = {
        { "some string", (void*)0x1234},
        { "some other string", (void*)0x5678},
        { "some third string", (void*)0x9abc},
        // ... etc
        {NULL} // To signal ending
};


void print_things(void *argument[][2]) {
    for(int i = 0; argument[i][0] /* using just argument[i] instead of argument[i][0] here would not work as intended */; ++i) {
        printf("%s %p\n", (char*)argument[i][0], argument[i][1]);
    }
}

int main(void) {
    print_things(g);
    return 0;
}

As a final note, I'd say your life would probably be simpler with a custom struct :

#include <stdio.h>

struct pair {
    char *str;
    void *ptr;
} g[] = {
        { "some string", (void*)0x1234},
        { "some other string", (void*)0x5678},
        { "some third string", (void*)0x9abc},
        // ... etc
        {NULL, NULL} // To signal ending
};


void print_things(struct pair argument[]) {
    for(int i = 0; argument[i].str; ++i) {
        printf("%s %p\n", argument[i].str, argument[i].ptr);
    }
}

int main(void) {
    print_things(g);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM