为什么此指针出现分段错误C



正如下面的代码一样,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 beginn");
    qsort(b,5,sizeof(int*),intcmp1);
    printf("cmp1 endn");
    printf("cmp1 beginn");
    qsort(b,5,sizeof(int*),intcmp);
    printf("cmp2 endn");
}

**((int**)a)不等于*((int*)(*(int*)a))吗?

否,**((int**)a)*((int*)(*(int*)a))不等价。第一个在上下文中是正确的:a实际上是指向传递给qsortint*数组元素的指针。**((int **)a)或简单地说**(int**)a读取要比较的整数。

相反,表达式*((int*)(*(int*)a))做了一些不同的事情:它从存储器中的同一地址读取,但作为int,然后假装这个int实际上是一个地址,并试图从该地址读取。如果int和地址没有相同的宽度,这将以惊人的失败告终。如果它们碰巧大小相同,它将在不便携的情况下成功。

此外,仅通过从另一个值中减去一个值无法可靠地比较int值。例如,INT_MIN < 1INT_MIN - 1调用未定义的行为,并且很可能向INT_MAX计算正值。

intcmp1应该这样重写:

int intcmp1(const void *v1, const void *v2) { // works better
    return (**(int**)v1 > **(int**)v2) - (**(int**)v1 < **(int**)v2);
}

<>比较运算符返回10,因此imtcmp1将精确地返回-101

相关内容

  • 没有找到相关文章

最新更新