结构数组上的c-qsort失败(分段错误11)



我是C的新手,来自纯Tcl脚本背景。

我有一个像这样的简单文件:

ship1 Canada 
ship4 China
ship5 USA 
ship2 UK
ship7 Taiwan
ship6 USA 
ship3 Singapore
ship11 Norway
ship8 Senegal

我有一个函数,它读取这个文件,创建一个structs数组并返回那个文件。

// 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] = '';
//printf("%sn", 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,这会导致seg错误。

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:%sn", s_origin[i].ship_name);
}   
fclose(fp);
return 0;
}

qsort中使用的我的cmp函数比较s_origin:的每个struct元素中的ship_name行

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非常不同。它只是在qsort处显示stop_reason=EXC_BAD_ACCESS

谢谢。

在尝试存储多个数据时,只为s_map分配了一个元素。

您应该像这样重新分配阵列:

while( (fgets(line, MAXLINE, fp)) != NULL) {
int len = strlen(line);
line[len -1] = '';
//printf("%sn", 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)而是sizeof(*s_origin)

线路char *line = malloc(sizeof(MAXLINE));也是错误的
这里没有显示,我猜MAXLINE是一个整数,它的大小最多应该是8个字节,而行会更长,所以会发生缓冲区溢出
应该是char *line = malloc(MAXLINE);

最新更新