简体   繁体   中英

How to pass void pointer around correctly?

I want to return my struct pointer as a void pointer. In this function when I print the noOfTuples I correctly get zero.

typedef void* HashjoinDatabase;
HashjoinDatabase HashjoinAllocateDatabase(unsigned long totalNumberOfEdgesInTheEnd) {
  HashjoinDatabase db;
  
  struct database* d = malloc(sizeof(struct database));
  if(d == NULL) {
    puts("Some kind of malloc() error");
  }

  d->tuples = malloc(totalNumberOfEdgesInTheEnd * sizeof(struct tuple));
  if(d->tuples == NULL) {
    puts("Some kind of malloc() error");
  }

  d->noOfTuples = 0;
  db = &d;
  printf("Hello %i\n", d->noOfTuples);
  return db;
}

However when in main I cast the returned void pointer back to the struct pointer and try to get the same noOfTuples and I get large varying values with each run which I suspect are addresses

int main() {
  HashjoinDatabase testDB = HashjoinAllocateDatabase(10);
  int no = ((struct database*)testDB)->noOfTuples;
  printf("Hello %i", no);
  return 0;
}
struct database* d = malloc(sizeof(struct database));

d is of type "pointer to struct database ".

db = &d;
// ...
return db;

You are assigning to db , and returning, the address to "pointer to struct database ".

int no = ((struct database*)testDB)->noOfTuples;

You are interpreting the address of "pointer to struct database " as "pointer to struct database ", so noOfTuples is no such thing.

And that is why you should pass around "pointer to datatype", not "pointer to void " (and avoid casting), so the compiler can actually warn you if you get the types wrong. ;-)

You're making things more complicated than they are.

You probably want this:

struct database* HashjoinAllocateDatabase(unsigned long totalNumberOfEdgesInTheEnd) {
  struct database* d = malloc(sizeof(struct database));
  if (d == NULL) {
    puts("Some kind of malloc() error");
    exit(1);
  }

  d->tuples = malloc(totalNumberOfEdgesInTheEnd * sizeof(struct tuple));
  if (d->tuples == NULL) {
    puts("Some kind of malloc() error");
    exit(1);
  }

  d->noOfTuples = 0;                    // why put this to 0 btw?
  printf("Hello %i\n", d->noOfTuples);  // shouldn't it be rather totalNumberOfEdgesInTheEnd ?
  return d;
}


int main() {
  struct database *testDB = HashjoinAllocateDatabase(10);
  int no = testDB->noOfTuples;
  printf("Hello %i", no);
  return 0;
}

There is no need for using void* here. Nor is there any need to hide a pointer type behind a typedef.

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