为什么这个指针有一个Segmentation fault C?

时间:2015-04-05 19:11:39

标签: c pointers segmentation-fault

正如以下代码一样,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))

1 个答案:

答案 0 :(得分:1)

不,**((int**)a)*((int*)(*(int*)a))不相同。第一个在上下文中是正确的:a确实是指向传递给int*的{​​{1}}数组的元素的指针。 qsort或只是**((int **)a)读取您要比较的整数。

相反,表达式**(int**)a做了不同的事情:它从内存中的相同地址读取,但作为*((int*)(*(int*)a))读取然后假装此int实际上是一个地址并尝试读取从那个地址。如果int和地址的宽度不同,则会失败。它们恰好是相同的大小,它将成功移植。

此外,您无法通过从另一个中减去一个来可靠地比较int值。例如intINT_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-10正好。{/ p>