«ошибка сегментации», вероятно, вызвана выделением памяти в C - PullRequest
0 голосов
/ 02 июня 2018

В этом коде я хотел бы найти самое длинное слово в предложении, в котором я остановился на ошибке сегментации, которая, по моему мнению, связана с распределением памяти в функции longestEvenWord () собирается вернуть переменную «res»;Кажется, Res не назначить правильно.При запуске GDB я получаю следующую ошибку

Program received signal SIGSEGV, Segmentation fault.
_IO_vfprintf_internal (s=0x0, format=0x400d22 "%s\n", 
ap=ap@entry=0x7fffffffdca8) at vfprintf.c:1275
1275    vfprintf.c: No such file or directory.

Вот код

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* readline();
char* longestWord();

int main(){
  FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");
  char* sentence = readline();
  char* res = longestWord(sentence);
  fprintf(fptr, "%s\n", res);
  fclose(fptr);
  return 0;
}

char* readline() {
  size_t alloc_length = 1024;
  size_t data_length = 0;
  char* data = malloc(alloc_length);
  while (true) {
    char* cursor = data + data_length;
    char* line = fgets(cursor, alloc_length - data_length, stdin);
    if (!line){ 
         break; 
    }
    data_length += strlen(cursor);
    if (data_length < alloc_length - 1 || data[data_length - 1] == '\n'){ 
         break; 
    }
    size_t new_length = alloc_length << 1;
    data = realloc(data, new_length);
    if (!data) { break; }
    alloc_length = new_length;
  }
  if (data[data_length - 1] == '\n') {
    data[data_length - 1] = '\0';
  }
  data = realloc(data, data_length);
  return data;
}


char* longestWord(char* sentence) {
 char res[134] = "00";
 char word[134];
 char s[134];
 strcpy(s, sentence);
 memset(word,0,strlen(word));
 int l, c = 0, max = -1;
 l = strlen(s);
 for(int i = 0 ; i < l ; i++){
    if(s[i] != ' '){
        word[c]= s[i] ;
        c++;
    }else{
          if(c > max) {
             word[c+1]='\0';
             max = c;
             strcpy(res, word);
         }
        c = 0;
        memset(word,0,strlen(word));
    }
 }
 if(c > max) {
      max = c;
      strcpy(res, word);
 }
 return res;
}

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

В Википедии есть статья, Dangling Pointer , которая хорошо объясняет проблему вашего кода.

Короче говоря, все автоматические переменные теряют контроль над памятью после возврата из функции.Следовательно, нельзя предполагать, что адрес, по которому вы сохранили некоторые данные, останется нетронутым;другая функция могла бы переопределить это место, например.

Вы можете сделать res динамическим, используя malloc, и инициализировать с помощью strcpy, как показано ниже.

char *res = (char *)malloc(134 * sizeof(char));
strcpy(res, "00");

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

0 голосов
/ 02 июня 2018

Есть ли вероятность того, что эта линия является вашей проблемой?FILE * fptr = fopen (getenv ("OUTPUT_PATH"), "w");

fopen может завершиться ошибкой и вернуть NULL по многим причинам, не связанным с повреждением памяти. Возможно, добавьте строку сразу после вышеупомянутойкак:

if (fptr == NULL) { perror(“fopen failed”); exit(1); }
...