【问题标题】:How to create an array of struct pointers to NULL如何创建指向 NULL 的结构指针数组
【发布时间】:2015-12-03 11:52:35
【问题描述】:

我想创建一个结构指针数组并将每个指针设置为空。最终我想让数组中的指针指向我的结构。我相信我有为此编写代码,但我一直遇到段错误。

代码:

//struct in my .h
struct bin{
 double cac; // current available capacity
 struct node *list //pointer to linked list... bin struct points to linked list struct
}
//main file
void main(){
 struct bin *bArray[20];
 struct bin *binTemp, *pTemp;
 for(i=0;i<20;i++) bArray[i]= NULL;
}

我以为这会创建一个 bin 指针数组,但我在这里遇到了段错误。不管它们是什么类型的指针,我不应该让所有指针都为 NULL 吗?

最终我想让这些都指向 bin 结构,我想我可以做到这一点而不必先将指针设为 NULL,所以我尝试了:

for(i=0;i<20;i++){
  binTemp = (struct bin *)malloc(sizeof(struct bin));
    binTemp->cac = 1.0;
    binTemp->list = NULL;
    bArray[i] = binTemp;
}   

我又遇到了段错误。我不知道这里发生了什么。我知道段错误意味着我正在尝试写入非法内存位置,这让我认为我必须使用 malloc 设置数组索引的大小。然而,

for(i=0;i<20;i++) bArray[i]= malloc(sizeof(struct bin));

也给了我一个段错误。我不知道我做错了什么。

我运行的实际代码:

//Header File

#ifndef hBin_h
#define hBin_h

#include <stdio.h> // stdio used for file io
#include <stdlib.h> // standard c library 

#define MAX_S 20


//bin struc
struct bin {
    double cac; //current available capacity
    struct node *list; // pointer to linked list
};
//linked list node struct
struct node{
    char *name; //name of item
    double size; // weight of item
    struct node *next; //pointer to next
};

//insert the new item into a node in its appropriate location using alphabetical ordering of item names
struct node *oInsert(char *item, double size, struct node *head);
//print the items of the list out along with the list’s capacity
void traverse(struct node *head);
// deallocate the nodes of the list
void destory(struct node *head);
//input info from file - name of object, weight of object
void input(FILE *inFile, char item[], double *weight);

#endif // hBin_h

#include "hBin.h"



void main(){
  FILE *inFile;
  char *item;
  double *weight;
  struct bin *bArray[20];
  int i;

  struct bin *binTemp, *pTemp;


  inFile = fopen("run1.txt", "r"); //open file
  printf("HERE1\n");

  for(i=0;i<20;i++){
      binTemp = (struct bin *)malloc(sizeof(struct bin));
      binTemp->cac = 1.0;
      binTemp->list = NULL;
      bArray[i] = binTemp;
  }   


/*while(!feof(inFile)){
input(inFile, item, weight);
printf("%s, %.2f\n", item, *weight);
}*/
}

我使用了 gdb(不完全确定我在这里做什么):

(gdb) run
Starting program: /home/Christopher/CSC362/Pass_F/Main
[New Thread 813244.0xc7590]
[New Thread 813244.0xc6ce0]
[New Thread 813244.0xc7320]
[New Thread 813244.0xc5994]
HERE1
      0 [main] Main 813244 cygwin_exception::open_stackdumpfile: Dumping stack trace to Main.exe.stackdump
[Thread 813244.0xc7320 exited with code 35584]
[Thread 813244.0xc6ce0 exited with code 35584]
[Inferior 1 (process 813244) exited with code 0105400]
(gdb) where
No stack.
(gdb) for(i=0;i<20;i++){
    binTemp->cac = 1.0;
    binTemp->list = NULL;
    bArray[i] = binTemp;
}   /usr/src/debug/cygwin-2.2.1-1/winsup/cygwin/crt0.c: No such file or     directory.
(gdb)   binTemp = (struct bin *)malloc(sizeof(struct bin));
Undefined command: "binTemp".  Try "help".
(gdb)     binTemp->cac = 1.0;
Undefined command: "binTemp->cac".  Try "help".
(gdb)     binTemp->list = NULL;
Undefined command: "binTemp->list".  Try "help".
(gdb)     bArray[i] = binTemp;
Undefined command: "bArray".  Try "help".
(gdb) }   for(i=0;i<20;i++){
Undefined command: "".  Try "help".
(gdb)   binTemp = (struct bin *)malloc(sizeof(struct bin));
Undefined command: "binTemp".  Try "help".
(gdb)     binTemp->cac = 1.0;
 Undefined command: "binTemp->cac".  Try "help".
 (gdb)     binTemp->list = NULL;
 Undefined command: "binTemp->list".  Try "help".
 (gdb)     bArray[i] = binTemp;
 Undefined command: "bArray".  Try "help".
 (gdb) }   for(i=0;i<20;i++){
 binTemp->cac = 1.0;
 Undefined command: "".  Try "help".
 (gdb)   binTemp = (struct bin *)malloc(sizeof(struct bin));
 Undefined command: "binTemp".  Try "help".
 (gdb)     binTemp->cac = 1.0;
 Undefined command: "binTemp->cac".  Try "help".
 (gdb)     binTemp->list = NULL;
 Undefined command: "binTemp->list".  Try "help".
 (gdb)     bArray[i] = binTemp;
 Undefined command: "bArray".  Try "help".

【问题讨论】:

  • 请贴出实际崩溃的代码,见MCVE
  • 如果bArraybinTemp 如您在第一个代码sn-p 中显示的那样声明,那么您显示的任何代码sn-ps 都不应该给您分段错误。请在调试器中运行崩溃程序以定位崩溃,它发生在您的代码中,并查看涉及的变量以查看是否有任何错误。哦,尝试创建一个Minimal, Complete, and Verifiable Example 并向我们展示。
  • 顺便说一下,如果你没有包含正确的头文件,中间的例子,你转换malloc的结果,实际上可能会导致未定义的行为和崩溃。请参阅"Do I cast the result of malloc?" 了解更多信息。
  • 不是。一方面它不能编译,另一方面没有#include 语句,而且它不会像给定的那样崩溃。问题在于您没有发布的代码。
  • @CinCity 我假设您尝试在评论中添加代码?不要那样做!它不会被格式化并且基本上不可读。而是编辑您的问题以包含重要的相关信息。

标签: c arrays pointers struct malloc


【解决方案1】:

阅读您注释掉的代码,将变量weight 传递给input 函数,并在调用printf 后立即取消引用它。这里有个大问题,那就是变量weight没有初始化,传递给一个函数按值传递,也就是说变量被复制了 并且该函数仅对副本而不是原始函数进行操作,这意味着您的 main 函数中的 weight 变量在您取消引用它时仍将未初始化,这会导致 未定义的行为和可能的崩溃。

如果你打算模拟引用传递(你只能模拟,因为C没有引用传递),你应该将weight声明为一个普通变量,并使用地址-调用函数时的操作符:

double weight;

...

input(inFile, item, &weight);
//                  ^
//                  |
// Note ampersand here

item 变量也有类似的问题。它是未初始化的,并没有指向任何特别之处。除了初始化之外,以任何方式使用它都会导致未定义的行为。如果你尝试在input 函数中初始化它,那么你会遇到与上述相同的问题,你需要使用address-of 运算符将指针传递给指针。

如果您input 函数中初始化item 指针,但使用它就像它已经指向一些有效内存(使用例如strcpy 或类似函数)然后你有未定义的行为。


您遇到的实际崩溃可能与我上面描述的问题完全无关,因为您似乎正在做一些涉及链表的事情,这当然意味着指针,而错误使用的指针会给您带来更多未定义行为的机会和崩溃。

您应该做的第一件事是在构建时启用更多警告,因为编译器通常非常擅长发现可能导致 UB 的可疑行为。你可以通过添加例如构建时的标志-Wall -Wextra -pedantic

【讨论】:

  • void input(FILE *inFile, char item[], double *weight){ fscanf(inFile, "%s %lf", item, weight); //scan info from text file } 这是我的输入功能。当我将它放在 bin 结构的 for 循环之上时,它可以正常工作,但是如果我将 if 放在 bin 结构 for 循环之后,我会再次遇到段错误。
  • @CinCity 如果您使用那些未初始化的指针,无论何时何地调用该函数,该函数都会为您提供未定义的行为。关于未定义行为,需要记住的重要一点是,有时它可能似乎工作正常(但实际上会做错事,比如写入未知的内存位置)。
  • 所以我应该做类似double weight = 0; for (int i=0; i&lt;20; i++) item[i]='\0';
  • @CinCity 不,你应该做类似char item[256];
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-30
  • 2011-02-01
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
相关资源
最近更新 更多