【问题标题】:Passing custom structure as argument causing segmentation fault将自定义结构作为参数传递会导致分段错误
【发布时间】:2021-04-07 11:37:52
【问题描述】:

在为一个 CS 类项目实现图表时,我声明了这两个结构

typedef struct person {
   char name[128];
   int age;
} Person;

typedef struct graph {

   int knots;
   int adjacencies[500][500];
   Person personList[500];
  
} Graph;

void insertPerson(Graph *g, Person p) {
   g->personList[knots] = p;
   (g->knots)++;
}

void writeAdjacencies(Graph g) {

  for(int i = 0; i < MAXDIM; i++) {
   for(int j = 0; j < MAXDIM; j++) {
     printf("%d ", g.adjacencies[i][j]);
    }
   printf("\n");
  }

}

一切都很好,除了在尝试创建菜单功能(读取输入然后决定是添加新人还是删除现有人等)时,传递一个图形指针然后使用它的指向实例似乎正在生成分段错误。

void checkInput(int input, Graph *g) {

  int temp;
  char tempName[128];


  if(input == 1 ) {

    printf("\n  Name: ");
    scanf(" %[^\n]", tempName);
    printf("%s\n", tempName);

    Person p; 
    strcpy(p.name, tempName);

    /* takes graph pointer a person and just adds person to personList and increases knots
       it's working as intended
    */
    insertPerson(g, p); 

    /* Goes through each element in the matrix and prints it
       this is the one causing problems
    */
    writeAdjacencies(*g); 

  }
  
}

在我将 *g 作为参数传递之前,代码工作正常 - 也就是说,如果我将 writeAdjacencies(*g) 放在注释下,它不会造成任何问题。

我不明白这里有什么问题?我觉得好像我在使用指针,就像我全年所做的那样,它奏效了。也许我可以传递一个空指针?但我确实在我认为的 main 函数中初始化了它。

main.c:


Graph graph;

for(int i = 0; i < MAXDIM; i++) {
 for(int j = 0; j < MAXDIM; j++) {
     g.adjacencies[i][j] = 0;
    }
 }
    
g.knots = 0;

checkInput(0, &g);

欢迎任何帮助!

编辑:包括两个缺失的功能

【问题讨论】:

  • 这不是一个最小的可重现示例。请edit您的问题,提供两个缺失函数的定义,
  • 您的 main 函数(就您已将其传达给我们而言)引用了变量 g 但未声明它。请提供minimal reproducible example(如果您还没有这样做,请阅读该链接——这将使您在 Stack Overflow 上的体验更加愉快)。
  • 没看过。完成。

标签: c pointers structure


【解决方案1】:

忽略scanf 代码中潜在的缓冲区溢出,您的Graph 结构对于堆栈(包含 250,000 个整数)来说太大了。请改用动态内存分配。例如:

typedef struct {
    int** adjacencies;
    int n;
} Graph;

void graph_init(Graph* g, int n) {
    g->n = n;
    g->adjacencies = malloc(n * sizeof(int*));
    for (int i = 0; i < n; ++i) {
        g->adjacencies[i] = malloc(n * sizeof(int));
    }
}

void graph_free(Graph* g) {
    for (int i = 0; i < g->n; ++i) {
        free(g->adjacencies[i]);
    }
    free(g->adjacencies);
    g->n = 0;
}

【讨论】:

  • 为了简单起见,教授不希望我们以这种方式分配内存。无论如何我都接受了你所说的,只是将尺寸从 500x500 更改为 20 似乎已经解决了它。那些潜在的缓冲区溢出是怎么回事?我真的不明白它的意思,但我会搜索它。非常感谢!
  • @Watisdis12 查看Wikipedia。在您的特定代码中,考虑如果用户在 scanf 输入期间输入超过 127 个字符会发生什么情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2017-11-02
相关资源
最近更新 更多