2014-12-07 2 views
0

У меня есть проблема с этим кодом. Работает так, как ожидалось, за исключением того, что в конце появляется ошибка Seg.Ошибка сегментации в конце программы

Вот код:

void distribuie(int *nrP, pach *pachet, post *postas) { 

    int nrPos, k, i, j; 
    nrPos = 0; 
    for (k = 0; k < 18; k++) 
     pos[k].nrPac = 0; 
    for (i = 0; i < *nrP; i++) { 
     int distributed = 0; 
     for (j = 0; j < nrPos; j++) 
      if (pac[i].idCar == pos[j].id) { 
       pos[j].vec[pos[j].nrPac] = pac[i].id; 
       pos[j].nrPac++; 
       distributed = 1; 
       break; 
      } 
     if (distributed == 0) { 
      pos[nrPos].id = pac[i].idCar; 
      pos[nrPos].vec[0] = pac[i].id; 
      pos[nrPos].nrPac = 1; 
      nrPos++; 
     } 
    } 
    for (i = 0; i < nrPos; i++) { 
     printf("%d %d ", pos[i].id, pos[i].nrPac); 
     for (j = 0; j < pos[i].nrPac; j++) 
      printf("%d ", pos[i].vec[j]); 
     printf("\n"); 
    } 

} 

и вызов этой функции в основной().

Запуск с помощью GDB в результате этой ошибки:

Program received signal SIGSEGV, Segmentation fault. 
0x00000001 in ??() 
+0

Вы сделали обратную трассировку на этой сессии 'gdb'? – WhozCraig

+1

Попробуйте запустить valgrind на нем ... вы, вероятно, беспорядок с памятью где-то Кроме того, почему nrP является указателем на int, если вы никогда не измените его значение? – Antzi

+0

@Antzi Бега с Valgrind показывает тот же: Процесса прекращения действия по умолчанию с сигналом 11 (SIGSEGV) == 15484 == Доступа не в пределах отображенной области по адресу 0x0 == 15484 == в 0x1: ??? НЕАРА РЕЗЮМЕ: == 15484 == в использовании на выходе: 390 байт в 10 блоках == 15484 == общего использования кучи: 10 ALLOCS, 0 высвобождает, 390 байт, выделенных == 15484 == == 15484 == LEAK SUMMARY: == 15484 == определенно потеряно: 390 байт в 10 блоках –

ответ

1

Если gdb не может найти трассировки стека, это означает, что ваш код написал стопку так тщательно, что ни один нормальный C среда, ни gdb может найти информация о том, где функция должна возвращаться в стеке.

Или, другими словами, у вас есть (основной) переполнение стека.

Где-то ваш код выписывает границы массива. Любопытно, что в коде размещены глобальные переменные pos и pac, но переданы (не используются) переменные postas и pachet. Это говорит о том, что код, который вы показываете, не является кодом, который вы выполняете. Однако, считая, что pos и pac действительно записаны так же, как и postas, и pachet, то может случиться так, что вы неправильно обращаетесь к своей функции distribuie(). (Если, как комментарий предполагает, pos и pac действительно являются глобальными переменными, то почему функции получить передается postas и pachet?)

Вы получаете какое-либо предупреждение компиляции? Вы включили предупреждения компиляции? Если у вас GCC, код легко компилируется с помощью -Wall? Как насчет -Wall -Wextra? Если вы получаете предупреждения, исправьте причины. Помните, на данном этапе вашей карьеры, вероятно, компилятор C знает больше о C, чем вы.

Вы можете помочь себе в отладке, напечатав значения ключа (например, *nrP) при входе в функцию. Если это не разумное значение, вы знаете, с чего начать искать. Вы также можете взять хороший взгляд на данные по линии:

pos[j].vec[pos[j].nrPac] = pac[i].id; 

Существует много места там для вещей, чтобы идти плохо в заблуждение!

1

Мне не хватает информации, чтобы полностью помочь вам: я не знаю размер массива pos []. Цикл с k < 18 предполагает, что это 18 элементов (но это может быть меньше, я просто не знаю). Затем вы начинаете обработку патчей nrP, но вы не проверяете, что вы обрабатываете не более 18 из них. Если их больше, вы перезаписываете другую память. Затем вы хотите напечатать результат et voila, ошибка сегментации, то есть некоторая память, поврежденная, используется кем-то, думающим, что это действительный pionter, но указатель недействителен и ... bang - segfault.

Таким образом, цикл должен, по крайней мере, проверить границы (в предположении, 18):

for (i = 0; i < *nrP && i < 18; i++) { 

Таким же образом, структура поз по-видимому, имеет массив VEC, но его размер неизвестен и тем же рассуждение может быть 18, может быть меньше или больше:

pos[j].vec[pos[j].nrPac] 

Если добавить всю вашу ограничивающую проверку он будет, вероятно, работать.

+0

Массив pos имеет максимальный размер 32. Кстати, если я зацикливаю k на 32, иногда возникает ошибка Seg, когда достигая k = 19, но не всегда. Почему? –

+0

Имеет «максимальный размер 32» (но может быть меньше) или «имеет размер 32»? Причиной seg foult не всегда является то, что память повреждена, и это может быть различным при каждом запуске программы. Такое поведение типично для коррупции памяти. –

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