【问题标题】:How to pass void pointer around correctly?如何正确传递 void 指针?
【发布时间】:2020-11-09 08:48:08
【问题描述】:

我想将我的 struct 指针作为 void 指针返回。在这个函数中,当我打印 noOfTuples 时,我正确地得到了零。

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;
}

但是,当我在 main 中将返回的 void 指针转换回结构指针并尝试获取相同的 noOfTuples 时,每次运行都会得到很大的变化值,我怀疑这些值是地址

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

【问题讨论】:

  • 在 typedef 后面隐藏结构是一回事,但是在 typedef 后面隐藏 pointer 是个坏主意。为什么不直接编写普通代码并返回正确的指向类型的指针?
  • 您的问题是您正在重新调整地址指针d,它是一个局部变量,在函数返回时超出范围。你想要db = d 或者只是`return d`。
  • 然后找到更好的课程... :-D
  • 请在此处指导您的讲师,以便专业人员向他/她解释他们的代码错误的原因。这是一种可怕的模式,因为有些人不懂 C 语言。
  • 将指针隐藏在 typedef 后面是个坏主意,但将 void* 隐藏在 HashjoinDatabase 等违反直觉的名称后面尤其不合逻辑。

标签: c


【解决方案1】:
struct database* d = malloc(sizeof(struct database));

d 是“指向struct database 的指针”类型。

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

您正在分配给db,并将地址返回到“指向struct database”的指针。

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

您将“指向struct database”的地址解释为“指向struct database”的指针,所以noOfTuples 不是这样的。

这就是为什么您应该传递“指向数据类型的指针”,而不是“指向void”的指针(并避免强制转换),因此如果您输入错误类型,编译器实际上会警告您。 ;-)

【讨论】:

  • 请不要typedef指针类型。它导致更多的混乱而不是它的价值......
【解决方案2】:

你让事情变得比现在更复杂。

你可能想要这个:

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;
}

这里不需要使用void*。也不需要在 typedef 后面隐藏指针类型。

【讨论】:

    猜你喜欢
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 2015-12-31
    • 2019-12-13
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多