【问题标题】:"segmentation fault" probably issued by memory allocation in C“分段错误”可能是由 C 中的内存分配发出的
【发布时间】:2018-11-12 12:58:57
【问题描述】:

在这段代码中,我想找到一个句子中最长的单词 我停止了一个分段错误,我认为这是由于函数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;
}

【问题讨论】:

  • 不能返回数组,必须返回指针。 res = malloc(SIZE);

标签: c pointers segmentation-fault gdb


【解决方案1】:

这条线有没有可能是你的问题? FILE* fptr = fopen(getenv("OUTPUT_PATH"), "w");

fopen 可能会失败,并由于许多与内存损坏无关的原因返回 NULL。也许在上面一行之后添加一行:

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

【讨论】:

    【解决方案2】:

    维基百科上有一篇文章,Dangling Pointer,很好地解释了你的代码的问题。

    简而言之,所有自动变量在从函数返回后都会失去对内存的控制。因此,不能假设您存储某些数据的地址会保持不变;例如,另一个函数可能覆盖了该位置。

    您可以使用malloc 使res 动态化,并使用strcpy 进行初始化,如下所示。

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

    确保在使用动态变量后释放它们,否则它们会导致内存泄漏,但在您的程序中不会有问题,因为它只是在打印res后结束。

    【讨论】:

    • 谢谢。但仍然遇到同样的问题,我认为它无法将 res 返回到主代码!
    • @teri:检查longestEvenWord 后,我发现memset(word,0,strlen(word)); 奇数为wordstrlen 调用的那一刻没有初始化。将其替换为 `word[0] = '\0;'告诉我它是否有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 2015-12-26
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    相关资源
    最近更新 更多