c - 结构数组上的 qsort 失败(分段错误 11)
问题描述
我是来自纯 Tcl 脚本背景的 C 新手。
我有一个像这样的简单文件:
ship1 Canada
ship4 China
ship5 USA
ship2 UK
ship7 Taiwan
ship6 USA
ship3 Singapore
ship11 Norway
ship8 Senegal
我有一个函数可以读取这个文件并创建一个结构数组并返回该文件。
// the return type of get_ship_info below is a pointer to struct that contains
// the ship information and the total number of ships counted so far
typedef struct ShipOrigin {
char *ship_name;
int ship_count;
} Ship_origin;
Ship_origin* get_ship_info(FILE*);
int cmp (const void *, const void *);
Ship_origin* get_ship_info(FILE *fp) {
char *line = malloc(sizeof(MAXLINE));
Ship_origin *s_map = malloc(sizeof(*s_map));
int i = 0;
while( (fgets(line, MAXLINE, fp)) != NULL) {
int len = strlen(line);
line[len -1] = '\0';
//printf("%s\n", line);
s_map[i].ship_name = malloc(sizeof(char)*MAXCHAR);
strcpy(s_map[i].ship_name, line);
s_map[i].ship_count = i;
i++;
}
s_map[0].ship_count = i;
return s_map;
}
在main
我调用它并使用 qsort 如下所示,这会导致段错误。
int main(int argc, char *argv[]) {
FILE *fp;
int i;
fp = fopen(argv[1], "r");
Ship_origin *s_origin = NULL;
s_origin = get_ship_info(fp);
int len = s_origin->ship_count;
qsort(s_origin,len, sizeof(s_origin), cmp);
for(i=0; i< s_origin->ship_count; i++) {
printf("SHIP DATA:%s\n", s_origin[i].ship_name);
}
fclose(fp);
return 0;
}
我在 qsort 中使用的函数比较了以下每个元素中cmp
的 ship_name 行:struct
s_origin
int cmp (const void *a, const void *b) {
Ship_origin* aa = (Ship_origin *) a;
Ship_origin* bb = (Ship_origin *) b;
return strcmp(aa->ship_name, bb->ship_name);
}
我是 C 的新手,我喜欢我正在学习的东西(由于失业和冠状病毒!)。请帮助我了解我做错了什么。
我也在学习 lldb 进行调试,这与调试 Tcl 非常不同。它只显示stop_reason=EXC_BAD_ACCESS
在qsort
.
谢谢。
解决方案
s_map
您在尝试存储多个数据时仅分配了 1 个元素。
您应该像这样重新分配数组:
while( (fgets(line, MAXLINE, fp)) != NULL) {
int len = strlen(line);
line[len -1] = '\0';
//printf("%s\n", line);
s_map = realloc(s_map, sizeof(*s_map) * (i + 1)); // add this
if (s_map == NULL) exit(1); // add this for safety
s_map[i].ship_name = malloc(sizeof(char)*MAXCHAR);
strcpy(s_map[i].ship_name, line);
s_map[i].ship_count = i;
i++;
}
的第三个论点qsort
也是错误的。它应该是要排序的元素的大小,所以它不应该是sizeof(s_origin)
but sizeof(*s_origin)
。
线路char *line = malloc(sizeof(MAXLINE));
也错了。
这里没有显示,我猜MAXLINE
是一个整数,它的大小应该最多 8 个字节,而行会更长,所以会发生缓冲区溢出。
应该是char *line = malloc(MAXLINE);
。
推荐阅读
- r - 使用 rstudio 和 github,重命名的 repo 问题
- php - Symfony CollectionType many to many relation in edit form
- debugging - 如何可视化 Elasticsearch 执行的查询历史
- python - 如何在 pandas read_csv 中设置千位分隔符?
- modelica - matrix singular under determined linear system not solvable
- amazon-web-services - 如何为自定义 cloudwatch 指标使用多个单独的维度?
- python - How to extract useful info from cProfile with Pandas and Numpy?
- r - 3D trajectory visualization with path in R
- java - Arcore - Frame keeps UpdatedTrackables after removing anchor
- javascript - 在 Google Apps 脚本中,如何让单个函数迭代跟踪许多不同变量对的数据结构?