2014-12-27 1 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 вместе с массивом целых чисел:

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

Смежные вопросы