2017-02-03 16 views
0

Я получаю ошибку на линии, где я положил знак «<<--» (строка 9). у него не было компиляционной ошибки, но при подаче ввода он говорит «Ошибка сегментации: 11». Я не знаю, что пошло не так.Я получаю ошибку сегментации: 11

вход:

3 3 
1 1 1 
2 2 2 
3 1 5 

Код:

#include <stdio.h> 
#include <stdlib.h> 

int comp (const void * x, const void * y) 
{ 
    int *a = *(int **)x; 
    int *b = *(int **)y; 

    //getting error here 

    if (a[0] == b[0]) // <<-- here 
    { 
     if (a[2] == b[2]) 
     { 
      return -(a[1] - b[1]); 
     } 
     else 
     { 
      return a[2] - b[2]; 
     } 
    } 
    else 
    { 
     return a[0] - b[0]; 
    } 
} 

int main() 
{ 
    int n; 
    long long d; 
    scanf("%d %lld", &n, &d); 

    int t[n][3]; 
    for (int i = 0; i < n; i++) 
    { 
     scanf ("%d %d %d", &t[i][0], &t[i][1], &t[i][2]); 
    } 

    printf("%lu\n", sizeof(t[0])); 
    qsort(t, n, sizeof(t[0]), comp); 

    for (int i = 0; i < n; ++i) 
    { 
     printf("%d-%d-%d\n", t[i][0], t[i][1], t[i][2]); 
    } 
} 

Может кто-нибудь помочь мне с этим?

+0

Добро пожаловать в переполнение стека. Вскоре прочитайте страницы [О программе] и [Спросить]. Вы печатали адреса, содержащиеся в 'a' и' b' в компараторе? Почему нет? Пробовали ли вы использовать отладчик с точкой останова на компараторе? –

+0

Обратите внимание, что ваш код будет иметь проблемы с вводом, где количество элементов в каждой строке не равно 3 (поэтому, если первая строка данных содержит '10 4', ваш код не будет обрабатывать размер 4 правильно). Это не сразу критично - ваш код, кажется, сбой, когда второй параметр равен «3» –

+0

при вызове любого из семейства функций 'scanf()' всегда проверяйте возвращаемое значение (а не значения параметра), чтобы гарантировать операция была успешной. – user3629249

ответ

3

Ваш

int t[n][3]; 

массив фактически 1D массив, состоящий из n 1D массивов типа int [3]. Эти int [3] объектов - это то, что вы пытаетесь отсортировать по

qsort(t, n, sizeof(t[0]), comp) 

звонок.

Итак, чтобы правильно сравнить эти объекты, вы должны интерпретировать параметры обратного вызова сравнения в качестве указателей на объекты int [3]. Между тем, ваша текущая реализация comp написана так, как если бы параметры указывали на int * объектов, что неверно. int [3] и int * - это две разные вещи.

Это, как вы можете сделать это

int comp (const void * x, const void * y) 
{ 
    int (*a)[3] = x; 
    int (*b)[3] = y; 

    // And now compare the arrays by accessing them as `(*a)[1]`, 
    // `(*b)[2]` and so on 
} 

В качестве альтернативы, вы можете написать код comp пролог, как

int comp (const void * x, const void * y) 
{ 
    const int *a = *(int (*)[3]) x; 
    const int *b = *(int (*)[3]) y; 

    // And now compare the arrays by accessing them as `a[1]`, 
    // `b[2]` and so on, i.e. keep the rest of your code unchanged 
} 

Это предполагает, что остальная часть вашей логики сравнения является правильным. Обратите внимание, что сравнение значений int путем вычитания их друг из друга является рискованным, поскольку оно может переполняться.

+0

сэр ваше первое решение показывает ошибку. «инициализация» int (*) [3] 'с выражением типа «const void *» отбрасывает квалификаторы [-Wincompatible-pointer-types-discards-qualifiers] «этот код работает» int (* a) [3] = (int (*) [3]) x; int (* b) [3] = (int (*) [3]) y; " вместо –