C 如何使用结构修复函数中的分段错误(内核转储)

C 如何使用结构修复函数中的分段错误(内核转储),c,C,尝试初始化函数,使其数据成员的数值为0,字符串为“无”,但strcpy出现分段错误 这是用于创建x、y点孤岛的2d数组的代码,在后续功能之前,我需要将函数初始化为默认值(0和无)。我曾试图弄乱指针,不使用strcpy,但据我所知,为了更新字符串,strcpy是必需的 typedef struct Hill { char name[20]; int loc[2]; double height; double slope; } Hill; Hill* setHill (Hill*

尝试初始化函数,使其数据成员的数值为0,字符串为“无”,但strcpy出现分段错误

这是用于创建x、y点孤岛的2d数组的代码,在后续功能之前,我需要将函数初始化为默认值(0和无)。我曾试图弄乱指针,不使用strcpy,但据我所知,为了更新字符串,strcpy是必需的

typedef struct Hill {
  char name[20];
  int loc[2];
  double height;
  double slope;
} Hill;

Hill* setHill (Hill* hill){
  strcpy(hill->name, "none");  // error appears to be here
  hill->loc[0] = 0;
  hill->loc[1] = 0;
  hill->height = 0;
  hill->slope = 0;
  return hill;
}
int main() {
   Hill* hillsArray[5];
   int i;

// calling setHill to populate an array of 5 hills
   for(i=0; i<5; ++i) {
     setHill(hillsArray[i]);
   }

// updating hill "ada's apex" 
strcpy((hillsArray[0]->name), "Ada's Apex");
hillsArray[0]->loc[0] = 12;
hillsArray[0]->loc[1] = 9;
hillsArray[0]->height = 20;
hillsArray[0]->slope = 0.25;

// updating hill turing's top
strcpy((hillsArray[1]->name), "Turing's top");
hillsArray[1]->loc[0] = 4;
hillsArray[1]->loc[1] = 3;
hillsArray[1]->height = 20;
hillsArray[1]->slope = 0.33;
typedef结构希尔{
字符名[20];
int loc[2];
双高;
双坡;
}山;
希尔*塞希尔(希尔*希尔){
strcpy(hill->name,“none”);//此处出现错误
希尔->位置[0]=0;
希尔->位置[1]=0;
山丘->高度=0;
山坡->坡度=0;
返回山;
}
int main(){
希尔*希尔数组[5];
int i;
//调用setHill填充5个Hill的数组
对于(i=0;iname),“Ada顶点”);
hillsArray[0]>loc[0]=12;
hillsArray[0]>loc[1]=9;
hillsArray[0]->高度=20;
hillsArray[0]->斜率=0.25;
//更新希尔图灵的顶部
strcpy((hillsArray[1]->名称),“图灵顶端”);
hillsArray[1]>loc[0]=4;
hillsArray[1]>loc[1]=3;
hillsArray[1]->高度=20;
hillsArray[1]->斜率=0.33;

此hill更新会重复3次,总共5个hill,但代码相同,只是用不同的值更新每个hill。

至少有一个问题,您没有为hill分配任何内存。
hill*hillsArray[5];
是一组
Hill
指针。它们不指向任何地方,因此当您执行
Hill->name
操作时,您取消了对坏指针的引用,这是一种未定义的行为,在您的情况下,它会表现为seg错误。您需要为每个
Hill
对象动态或自动分配内存,如下所示:

// dynamically (following what you have now)
int main() {
   Hill* hillsArray[5];
   int i;

// calling setHill to populate an array of 5 hills
   for(i=0; i<5; ++i) {
     hillsArray[i] = malloc(sizeof(hillsArray[0]));  // equivalent to malloc(sizeof(struct Hill));
     if (hillsArray[i] == NULL)
     {
       // in the case the malloc fails, handle the error however you want
       printf("Could not allocate memory for Hill %d\n", i);
       return 1;
     }
     setHill(hillsArray[i]);
   }
   ....
   // it's considered good practice to clean up memory you dynamically allocate,
   // although you will find differing opinions of that on SO, so up to you.
   // When your process exits, the OS will clean up any allocated memory, so
   // in this case, it's not all that important to clean it up yourself. But
   // for programs that run indefinitely, it's much more of a concern.
   for (i=0; i<5; i++)
   {
     free(hillsArray[i]);
   }
}
//动态地(遵循您现在拥有的内容)
int main(){
希尔*希尔数组[5];
int i;
//调用setHill填充5个Hill的数组

对于(i=0;i)我们可以看到代码中分配hill并调用setHill的部分吗?如果您没有分配hill并传递未初始化的指针,那么您将得到segfault。问题不在这里。问题在于调用setHill()的代码中。我猜代码没有hill对象将指针传递给setHill()。如果调用setHill(&hill),hill是在堆栈上而不是在堆上分配的变量,则可能会失败。您没有使用malloc,是吗?:pas已经提到,我们需要其余部分,并且您的hill引用可能为空。添加了与您的备注相关的附加代码。
// setup Hills in automatic storage instead
int main() {
   Hill hillsArray[5]; // each hill is in automatic storage, probably on the stack
   int i;

// calling setHill to populate an array of 5 hills
   for(i=0; i<5; ++i) {
     setHill(&(hillsArray[i]));  // now you must pass the address of each Hill to the setHill function
   }

   ....

   // since it's automatic storage, no need to clean it up yourself
}