Arhn - архитектура программирования

C — Ошибка сегментации при выделении места для строк

Этот код должен естественным образом сортировать массив строк, и он дает segfault. К сожалению, я не знаю, на каком вводе он дает segfault, но я предполагаю, что segfault происходит при выделении памяти для строк. Максимальная длина строки 9000000.

Вот:

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

void
strsort(char **string, int left, int right) {
   char *comp, *temp;
   int i, j, p;
   while(left < right) {
       i = left;
       j = right;
       p = (left + right) / 2;
       comp = string[p];
       while(1) {
           while(i <= j && strcmp(string[i], comp) <= 0)
               i++;
           while(i <= j && strcmp(string[j], comp) > 0)
               j--;
           if(i > j)
               break;
           temp = string[i];
           string[i] = string[j];
           string[j] = temp;
           if(j == p)
               p = i;
           i++; j--;
       }
       string[p] = string[j];
       string[j] = comp;
       j--;
       if((j - left) < (right - i)) {
           strsort(string, left, j);
           left = i;
       } else {
           strsort(string, i, right);
           right = j;
       }
   }
}

void
ignore_line(void) {
   char c;
   while((c = getchar()) != '\n');
}

int
main(void) {
   enum 
   {
       L = 9000001
   };
   int n, i, j, len;
   char offset = 'a' - 'A';
   scanf("%d", &n); ignore_line();
   char **string = (char **)malloc(n * sizeof(char *));
   for(i = 0; i < n; ++i) {
       string[i] = (char *)malloc(L * sizeof(char));
       len = -1;
       while((string[i][++len] = getchar()) != '\n') {
           if(string[i][len] >= 'a')
               string[i][len] -= offset;
           else
               string[i][len] += offset;
       }
       string[i] = (char *)realloc(string[i], len + 1);
       string[i][len] = '\0';
   }
   strsort(string, 0, n - 1);
   for(i = 0; i < n; ++i) {
       j = 0;
       while(string[i][j] != '\0') {
           if(string[i][j] >= 'a')
               printf("%c", string[i][j] - offset);
           else
               printf("%c", string[i][j] + offset);
           ++j;
       }
       printf("\n");
   }
   return 0;
}
27.11.2011

  • Было бы неплохо изучить, как использовать отладчик, чтобы вы могли воспроизвести свои тесты и посмотреть, какой ввод вызывает его смерть. 27.11.2011
  • Можете ли вы запустить это в отладчике и создать трассировку стека? Непосредственная ошибка, которую я вижу, заключается в том, что вы никогда не проверяете, действительно ли сработало распределение, вы должны ВСЕГДА проверять возвращаемое значение malloc, поскольку malloc вернет NULL в ситуациях нехватки памяти. 27.11.2011
  • Вы правы, но я уже потратил некоторое время на это и не смог найти такой вход. Тем не менее, это хорошая идея, чтобы попробовать еще раз. 27.11.2011
  • Спасибо, я проверю, прошло ли распределение успешно. 27.11.2011
  • Мое дикое предположение также заключается в том, что strsort вызывается рекурсивно, и вы получаете переполнение стека. Но отладчик покажет. (или детально прорабатывая логику) 27.11.2011
  • Попробуйте valgrind 27.11.2011
  • Я думаю, что проблема не в strsort, потому что я пробовал алгоритм итеративной сортировки, и это не имеет значения. 27.11.2011
  • @johannes +1 за использование переполнения стека в вашем ответе :) ти хи 28.11.2011

Ответы:


1

Ошибка первого сегмента выдается по адресу:

while(i <= j && strcmp(string[i], comp) <= 0)

Попробуйте просто отправить char* в strsort вместо char** и сравнить экземпляры char. Большая часть вашего кода слишком сложна.

void
strsort(char* string, int left, int right) {
   char comp, temp;

См. мою реализацию quicksort.

28.11.2011
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..