【问题标题】:How to pass a pointer to a structure properly如何正确传递指向结构的指针
【发布时间】:2019-03-30 16:21:59
【问题描述】:

我正在尝试在堆上创建一个结构 - 以便它可以在其他函数中使用,但我似乎无法克服以我可以传递的方式创建结构本身的第一个障碍用指针。我知道字段数组已正确初始化为 5 x 5,并且我可以获得指向 fieldz 结构的指针 (*f),但是当我尝试将它传递回 main 时,什么也没有出现。我需要保留 field_t * f = makeField(w,h);照原样,我觉得我错过了一些明显的东西。

谢谢!

struct _field_t {
  int ** field;
  int width;
  int height;
};
typedef struct _field_t field_t;

field_t * makeField(int w, int h){
  field_t fieldz;
  fieldz.width = w;
  fieldz.height = h;
  int ** fieldz = malloc(h * sizeof(* fieldz));
  for(int y = 0; y < h; y++){
    int * row = malloc(w * sizeof(* row));
    fieldz[y] = row;
    for(int x = 0; x < w; x++){
      row[x] = -1;
    }
  }
  fieldz.field = field;
  field_t * f = &fieldz;
  return f;
}
int main() {
  int h = 5;
  int w = 5;
  field_t * f = makeField(w, h);
  return 0;
}

【问题讨论】:

  • 这是重复的(必须搜索什么) - 您正在返回一个指向本地对象的指针,该对象在 makeField 调用完成时不存在。
  • @John3136 stackoverflow.com/q/17997228/251311 也许? (C++ 不是 C 但仍然是)或stackoverflow.com/q/5289015/251311
  • Can a local variable's memory be accessed outside its scope? 的可能副本我知道这是 C++ 但它给出了很好的解释。
  • 这段代码甚至无法编译。我在任何地方都没有看到field 声明? field_t fieldz; 后面还有 int ** fieldz。这是故意的吗?
  • 纯粹是形式问题,但至少将您的指针星号附加到类型或名称上(不会开始选择哪个圣战,但我们都只知道其中一个是对的)

标签: c


【解决方案1】:

(此答案将忽略错字int **fieldz

返回一个指向局部变量的指针是一个很大的禁忌。我不打算详细说明,因为这已经解释过很多次了(谷歌,bing 和鸭鸭去是你的朋友)

基本上有三种方法可以让函数创建结构

1 - 分配结构并返回指向它的指针:

field_t * makeField(int w, int h)
{
   field_t *f = malloc(sizeof (*f))
   f->width = w;
   f->height = h;
   f->field = .....;

   return f;
}
.....
field_t *f = makeField(50, 50);

2 - 让调用者分配内存并传递一个指向要初始化的结构的指针

field_t * makeField(field_t *f, int w, int h)
{
   f->width = w;
   f->height = h;
   f->field = .....;

   return f;
}
.....
field_t f1;
makeField(&f1, 50, 50);

field_t *f2 = malloc(sizeof(*f2));
makeField(f2, 50, 50);

3 - 让调用者分配内存并分配makeField创建的结构的副本

field_t makeField(int w, int h)
{
   field_t f;
   f.width = w;
   f.height = h;
   f.field = .....;

   return f;
}
.....
field_t f1 = makeField(50, 50);

field_t *f2 = malloc(sizeof(*f2));
*f2 = makeField(50, 50);

您使用哪种方法取决于需求和个人喜好。就个人而言,我更喜欢让调用者在可能的情况下分配内存。调用者通常更清楚堆栈、堆或其他东西是否更合适

【讨论】:

    猜你喜欢
    • 2013-09-02
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 2021-07-17
    相关资源
    最近更新 更多