一些前言:我是一名计算机工程专业的学生,经过3个学期的Java(直到数据结构),在C语言中取得了第一堂课。这个问题与家庭作业有关,但为我解决了一些步骤。
我有一个输入文件,我读入内存,以便存储在char [9] [500]中。我读入最多500个最大长度为8的字符串。我试图使用stdlib内置的qsort()函数对此数组进行排序,并且存在一些内存错误。
重要的代码片段:
char data[4][500][60];
char debug[500][9];
size_t count = 0;
/* initialize file, open for reading */
FILE* pUserlog;
pUserlog = fopen("userlog","r");
while(!feof(pUserlog))
{
fscanf(pUserlog, "%9s %8s %16s",debug[count], data[1][count], data[2][count]);
fgets(data[3][count], 60, pUserlog);
count++;
}
此部分将数据读入数组。这部分感兴趣的数组是“debug”。这是上面指定的数组。这是我对qsort的比较函数:
int compare(const void* a, const void* b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
puts("I'm in compare!");
return strncmp(*ia, *ib,8);
}
这是我尝试调用qsort:
size_t debug_len = sizeof(debug)/sizeof(char*);
printf("debug len: %d, count: %d, sizeof(char*): %d\n",debug_len,count,sizeof(char*));
qsort(debug,count, sizeof(char *), compare);
我试图在我的调用中替换debug_len,其中count是,但我仍然是segfaulting。这是输出:
$ ./test debug len: 1125, count: 453, sizeof(char*): 4 I'm in compare! Segmentation fault (core dumped)
谢谢!
答案 0 :(得分:9)
compare函数将接收指向要比较的元素的指针。您正在尝试使用strncmp()
比较字符。由于您有指向每个字符串的指针,因此将其强制转换为char *
并进行比较。
int compare(const void* a, const void* b)
{
const char *ia = (const char *)a;
const char *ib = (const char *)b;
puts("I'm in compare!");
return strncmp(ia, ib, 9);
}
还要记住,它是一个数组数组,而不是一个指针数组。因此元素的大小应该是数组的大小9
而不是指针4
的大小。此时,使用sizeof debug[0]
会更容易,因为它是一个二维数组。如果你没有使用正确的尺寸,qsort()
只会破坏你的阵列。
size_t elemsize = sizeof debug[0]; /* 9 - size of each element */
size_t count = sizeof(debug)/elemsize; /* 500 - number of elements in array */
qsort(debug, count, elemsize, compare);
答案 1 :(得分:4)
这里发生的是:你有500个字符串。现在你将所有500传递给qsort,然后它将每个传递给你的比较函数作为第一个和第二个参数。这有点像写这个:
compare(debug[0], debug[1])
C编译器传递地址,而不是实际值。但现在您将指向void的指针解释为指向指针的指针。您的代码现在在调用strncmp
时会取消引用,但这会使值(前4个字节)被视为strncmp
中的指针。但是strncmp
现在将依次尝试取消引用垃圾“指针”(它由你的一个字符串的一部分组成),这使得 bang 。
要解决此问题,请使用char *
代替char **
:
int compare(const void* a, const void* b)
{
puts("I'm in compare!");
return strncmp((const char *)a, (const char *)b, 8);
}