正如以下代码一样,intcmp1正确运行但是intcmp会出现段错误。我不知道为什么。这两个代码看起来一样。
我的系统环境是:OS X 10.10.2 64bit;铛
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int intcmp(const void *v1, const void *v2){ //Segment Fault
return (*((int*)(*(int*)v1)) - *((int*)(*(int*)v2)));
}
int intcmp1(const void *v1, const void *v2){ //No Problem
return (**(int**)v1-**(int**)v2);
}
int main(int argc, char *argv[]) {
int a[5]={0,1,2,3,4};
int **b,i;
b=calloc(5,sizeof(int*));
for(i=0;i<5;i++){b[i]=&a[i];}
printf("cmp1 begin\n");
qsort(b,5,sizeof(int*),intcmp1);
printf("cmp1 end\n");
printf("cmp1 begin\n");
qsort(b,5,sizeof(int*),intcmp);
printf("cmp2 end\n");
}
不是**((int**)a)
等于*((int*)(*(int*)a))
?
答案 0 :(得分:1)
不,**((int**)a)
和*((int*)(*(int*)a))
不相同。第一个在上下文中是正确的:a
确实是指向传递给int*
的{{1}}数组的元素的指针。 qsort
或只是**((int **)a)
读取您要比较的整数。
相反,表达式**(int**)a
做了不同的事情:它从内存中的相同地址读取,但作为*((int*)(*(int*)a))
读取然后假装此int
实际上是一个地址并尝试读取从那个地址。如果int
和地址的宽度不同,则会失败。它们恰好是相同的大小,它将成功移植。
此外,您无法通过从另一个中减去一个来可靠地比较int
值。例如int
但INT_MIN < 1
调用未定义的行为,并且很可能计算为INT_MIN - 1
,这是一个正值。
INT_MAX
应该以这种方式重写:
intcmp1
int intcmp1(const void *v1, const void *v2) { // works better
return (**(int**)v1 > **(int**)v2) - (**(int**)v1 < **(int**)v2);
}
和<
比较运算符返回>
或1
,因此0
将返回imtcmp1
,-1
或0
正好。{/ p>