Почему эта программа segfault - PullRequest
0 голосов
/ 14 мая 2010

После компиляции и запуска этой небольшой программы для обращения строки я получаю ошибку сегментации до того, как произойдет какой-либо вывод. Простите, если это очевидный вопрос, я все еще плохо знаком с C.

#include <stdio.h>

int reverse(char string[], int length); 

int main() {
char string[] = "reversed";

  printf("String at start of main = %s", string);
  reverse(string, sizeof(string));
  printf("%s\n", string);

return 0;

}

// Reverse string 
int reverse(char string[], int length) {
 int i;
 char reversed[] = {};
 int temp;

 for(i = 0; i < length; ++i) {
 temp = string[i];
 reversed[length - i] = temp;

 }
 return 0; 
}

Ответы [ 4 ]

6 голосов
/ 14 мая 2010

Из-за этого:

Сначала вы создаете массив с нулевыми элементами:

char reversed[] = {};

И позже вы пытаетесь записать в этот массив за его пределы:

reversed[length - i] = temp;

Обновление:

Вышеуказанное означает, что вам нужно выделить память, размер которой известен только во время выполнения (это length). Обычный способ сделать это в стиле C - это ... перенести бремя выделения памяти вызывающей стороне:

int reverse(const char* string, char* destination, int length);

Эта функция будет записывать в буфер, предоставленный вызывающей стороной, которая теперь также должна обеспечить:

  1. Буфер достаточно большой
  2. Память для буфера освобождается, когда она должна быть
3 голосов
/ 14 мая 2010

Хотя в этом случае это работает, обычно sizeof (строка) должна быть `strlen (строка). Обычно при использовании указателей на символы оператор sizeof просто возвращает размер одного указателя, а не всего массива. , В reverse () ваш обратный массив не выделен, вы можете выделить его следующим образом:

char* reversed = (char*) malloc( length+1 );

Мы добавляем один к длине, чтобы учесть нулевой символ в конце строки.

1 голос
/ 14 мая 2010

Ваш код не компилируется как C. Декларация

char reversed[] = {};

недействительно. В языке C нет такого понятия, как пустой инициализатор {} (он существует только в C ++). Более того, пустой инициализатор не будет иметь никакого смысла в объявлении массива неопределенного размера (что делает этот код некомпилируемым как C ++), так как нет такого понятия как массив нулевого размера ни в C, ни в C ++. *

Либо отправьте реальный код, либо повторно задайте свой вопрос, если предполагается, что это C ++.

0 голосов
/ 14 мая 2010

В C вы должны тщательно продумать память, занимаемую вашими переменными и массивами.

Когда вы пишете char reversed[] = {}, вы создаете новый массив нулевого размера. (Это, очевидно, не совсем правильный C, но - это , что происходит с компилятором gcc спрашивающего. В конце концов, отчет содержит ошибку сегментации во время выполнения, а не синтаксическую ошибку во время компиляции.)

Затем оператор reversed[length - i] пытается записать данные в элемент массива, для которого у вас нет места, потому что reversed не имеет размера.

У вас есть два варианта:

  • Создайте массив reversed правильного размера (возможно, используя malloc, как говорит @ Боб Кауфман) , а затем верните его из reverse() функции .
  • Переверните строку «на месте», сместив символы вокруг самого string.

Смена строки на месте, вероятно, предпочтительнее - если вы выделяете память динамически, вам придется беспокоиться о ее освобождении, что может быть проблемой.

...