Почему моя программа на C с любым вводом приводит к ошибке сегментации?

Я часами ломал голову над тем, почему это не работает.

#include <stdio.h>
#define MAXLINE 1000
#define TRUE 1
#define FALSE 0

int getLine(char s[], int lim);
void copy(char to[], char from[]);
void add(char to[], char from[], int max);

int main(){
  int len;
  int max;
  char line[MAXLINE];
  char longest[MAXLINE];

  max = 0;
  len = 0;
  while(( len = getLine(line, MAXLINE)) > 0){
    
    if (max == len){
      add(longest, line, max);
    }

    if (len > max){
      max = len;
      copy(longest, line);
    }
  }
  
  if (max > 0){ 
    printf("%s", longest);
  }
  return 0;
}
int getLine(char s[], int lim){
  int c, i;
  
  for (int state = FALSE, i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n';){
    if (c == '\t' || c == ' ' && state == TRUE)
      continue;

    if (c == '\t' || c == ' '){
      s[i] = c;
      ++i;
      state = TRUE;
    } else {
      s[i] = c;
      state = FALSE;
      ++i;
    }
  }
  if (c == '\n'){
    s[i] = c;
    ++i;
  }
  s[i] = '\0';

  return i;
}

void copy(char to[], char from[]){
  int i = 0;

  while((to[i] = from[i]) != '\0'){
    ++i;
  }
}

void add(char to[], char from[], int max){
  if (max != 0){
    int control = max * 2;
    to[max] = from[0];
    ++max;
    for(int i = 1; max <= control; ++max, ++i ){
      to[max] = from[i];
    };
  };
}

Я что-то пропустил ? Я запустил valgrind с такими результатами

==22786== Memcheck, детектор ошибок памяти

==22786== Авторские права (C) 2002–2017 гг. и лицензия GNU GPL, Джулиан Сьюард и др.

==22786== Использование Valgrind-3.18.1 и LibVEX; повторите запуск с -h для получения информации об авторских правах

==22786== Команда: ./maxLine

==22786==

как

==22786== Использование неинициализированного значения размера 8.

==22786== по адресу 0x10933A: getLine

==22786== по 0x109230: основной

==22786==

==22786== Использование неинициализированного значения размера 8.

==22786== по адресу 0x10934D: getLine

==22786== по 0x109230: основной

==22786==

==22786== Условный переход или перемещение зависит от неинициализированных значений.

==22786== по адресу 0x10923E: основной

==22786==

==22786== Условный переход или перемещение зависит от неинициализированных значений.

==22786== по адресу 0x1091C9: основной

==22786==

==22786== Условный переход или перемещение зависит от неинициализированных значений.

==22786== по адресу 0x1091F6: основной

==22786==

==22786== Условный переход или перемещение зависит от неинициализированных значений.

==22786== по адресу 0x109396: скопировать

==22786== по 0x10921C: основной

==22786==

В БДБ:

[Отладка потоков с использованием libthread_db включена]

Использование хост-библиотеки libthread_db "/lib/x86_64-linux-gnu/libthread_db.so.1".

как

Программа получила сигнал SIGSEGV, ошибка сегментации.

0x000055555555533a в getLine (s=0x7ffffffd7e0 "as\377\367\377\177", lim=1000) в maxLine.c:53

53 с[и] = с;

(gdb) обратная трассировка

#0 0x000055555555533a в getLine (s=0x7ffffffd7e0 "as\377\367\377\177", lim=1000) в maxLine.c:53

#1 0x0000555555555231 в main() в maxLine.c:18

Я не знаю, с чего начать

Еще одно примечание, в дополнение к данному ответу: похоже, что c == '\t' || c == ' ' && state == TRUE вы можете добавить круглые скобки, чтобы зафиксировать приоритет, если вы хотите, чтобы STATE соответствовало и вкладкам.

Thomas Jager 11.07.2024 12:59

При запросе помощи по отладке предоставьте минимально воспроизводимый пример, включая точную копию входных данных, воспроизводящих проблему. «Любой вход» — неподходящее описание. Возможно, вы пробовали различные значения для некоторых форм ввода, подходящих для программы, но кто-то, кто впервые обращается к вашей программе, может не знать, какая форма ввода подходит для программы. А наличие конкретного конкретного примера помогает отладке и общению о программе.

Eric Postpischil 11.07.2024 13:00

valgrind и gdb будут более полезны, если вы перекомпилируете программу, добавив -g -Og в командную строку.

zwol 11.07.2024 14:29
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
3
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В getline for (int state = FALSE, i = 0; … объявляет i, который существует только во время выполнения оператора for. Значение i, объявленное ранее в подпрограмме, не затрагивается. Тот, что раньше i, не инициализирован. Тот, что раньше, i используется позже в подпрограмме без инициализации.

Большинство компиляторов диагностируют это. Компилируйте с включенными предупреждениями и повышенным уровнем ошибок. В Clang начните с -Wmost -Werror. При использовании GCC начните с -Wall -Werror. В MSVC начните с /W3 /WX.

Могут быть и другие ошибки в программе.

Другие вопросы по теме