2014-12-27 86 views
1

这是我比较功能:比较整数功能SIGSEGV

int compareInts(const void *a, const void *b) { 
    const int *pa = (const int*)a; 
    const int *pb = (const int*)b; 
    return *pa - *pb; 
} 

当我通过这个函数整数数组来快速排序一起:

qsort(a, size, sizeof(char*), compareInts); 

一切正常,我也得到一个排序列表。但是,如果我尝试使用它自己:

compareInts(2, 2); 

,我收到了SIGSEGV,除非我修改的功能如下:

int compareInts(const void *a, const void *b) { 
    const int *pa = (const int*)a; 
    const int *pb = (const int*)b; 
    return pa - pb; 
} 

当我打电话,但通过时的qsort返回无序到工作正常名单! 这是怎么回事?

+0

“qsort()”的第三个参数是每个元素的大小。如果你实际上对一个'int'数组进行排序,那么第三个参数应该是sizeof(int)或者sizeof(* a)'。 – Blastfurnace

+0

'2'不是一个指针,函数需要两个指针。所以它认为'2'是一个指针,并将其视为这样。访问超出过程数据限制的地址2会导致导致seg故障事件的未定义行为。程序的第二个版本是比较指针,而不是指针指向什么。 – user3629249

回答

2

试试这个:

int a=2; 
int b = 2; 
compareInts(&a, &b); 

你比较函数接受指针,而不是直接整数。 当你在

compareInts(2,3); 

传递两个整数真的会发生什么事是你在告诉这个功能去和分别在内存地址0x00000002和0x00000003找到你的整数,而这些都不是有效的地址。

在您修改后的函数中,您将比较两个指针0x00000002和0x00000003的值,而不尝试解除引用它们,因此它不会崩溃。

+0

“,而不是试图解除引用它们” - >应该是“在您的调用中不传递它们的*地址*,而不是仅仅传递原始值”2“(即存储在*地址*中的*值*)。希望得到一个*地址*。OP的问题正在发生*具体是因为他/她试图解引用它们 – frasnian

+0

为什么它和qsort一起工作? – user2506293

+0

在你修改后的函数中,你正在比较指针中的值qsort另一方面,两个值一次正确比较,意味着它做了类似于compareInts(&arr [i],&arr [j])的东西,所以它的工作原理就是:qsort不关心compareInts与值做什么 - 它只是期望一个整数结果。如果你使用qsort修改过的函数,你将会比较内存地址而不是数值。 – DNT

1

有了这个代码:

compareInts(2, 2); 

您正在尝试与存储位置2.比较内存位置2这会给你一个段冲突,只是因为你没有访问内存位置2.您不要试图比较两个位于您有权访问的内存地址 - 在操作系统意识到您无法访问这些位置之前,您甚至无法达到该点(并且会给您一个很大的SEGV感谢 - 换尝试)。您需要比较您实际访问的内存地址的内容。例如:

int a = 2; // a is an integer variable, you can take the address of this 
    int b = 2; // ibid 

    compareInts(&a, &b); // now, you are giving your function *the addresses of* a and b 
+0

与@DNT重叠 - 如果您打算接受其中一个答案,请为他打字 - 慢打字的日子。 – frasnian