【问题标题】:Segmentation fault, fgets in while loop分段错误,fgets 在 while 循环中
【发布时间】:2016-09-16 17:34:30
【问题描述】:

我尝试多次而不是一次读取文件。 在尝试时,我遇到了很多分段错误。带有 while 循环的程序部分如下所示:

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

/* General use buffer */
#define STRLEN 8196
char    string[STRLEN];


int lines = 1024;
char    **line;
int linemax;

int longest=0;


int main(){
int len,i;
int zwei = 1;
FILE * fp;
char    *s;
int debug =  0;
line=(char **)malloc(sizeof(char *) * 1024);
do{
    if ( (fp = fopen("rhel7_160731_0606.nmon", "r")) == NULL) {
        perror("failed to open file");      

                perror("fopen");
        exit(75);
    }
printf("where is the problem1,3\n");
    for (i = 0; fgets(string, STRLEN, fp) != NULL; i++) {
        if (i >= lines) {
            lines += 1024;
            line = (char **)realloc((void *)line, sizeof(char *) * lines);
        }

        if (string[strlen(string)-1] == '\n')
            string[strlen(string)-1] = 0;
        if (string[strlen(string)-1] == '\r')
            string[strlen(string)-1] = 0;
        if (string[strlen(string)-1] == ' ')
            string[strlen(string)-1] = 0;
        if (string[strlen(string)-1] == ',')
            string[strlen(string)-1] = 0;
        len = strlen(string) + 1;

        if (len > longest)
            longest = len;
        s = malloc(len);
        strcpy(s, string);
        line[i] = (char *)s;
    }
    linemax = i;
    lines = i;

    if (debug)
        for (i = 0; i < linemax; i++)
            printf("line %d lastline %s\n", i, line[i-1]);

zwei++;

}while(zwei<4);

return 0;
}

它什么都不挂起或以分段错误结束。

【问题讨论】:

  • 你的调试器说什么?
  • 程序收到信号SIGSEGV,分段错误。 0x00000000004009df in main () at test.c:53 53 line[i] = (char *)s;
  • 那是哪个调试器?
  • 所以现在会发生这种情况:#0 __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95 #1 0x00007ffff7a8924b in _IO_fgets (buf=0xeb2d50 "\ 002", n=8196, fp=0xea1c40) at iofgets.c:50 #2 0x000000000040a7f9 in main (argc=8, argv=0x7fffffffdf68) 它运行了两次然后出现问题。是缓冲区溢出吗?
  • } while(zwei&gt;4); 从来都不是真的,所以它不能循环两次,这不是原因,但我想知道还有多少是粗心的。

标签: c linux while-loop fopen fgets


【解决方案1】:

您似乎忘记为line 分配内存。它在这里失败了:line[i] = (char *)s。我认为您需要将lines 设置为零,因为只有当您的迭代器ilines 增长时,您才会重新分配line

另外,解决这个问题:while(zwei &gt; 4)while(zwei &lt; 4)。而且,您需要将您分配的内存分配给free - 因为您将所有指针存储在line 中,所以它不会很复杂 - 只需一个循环。

【讨论】:

  • 这是一个全局变量,因此初始化为realloc 可以处理的0NULL。但这是一个很好的收获。
  • @WeatherVane 我的意思是,他试图在line[i] 中写入数据,但line,正如您所说的,默认设置为NULL
  • 如何释放内存?
  • @bastel 在单个循环中使用free( line[i] ),例如for 循环。我已经处理了它,在while 语句之前放置了以下循环:for (i = 0; i &lt; lines; i++){free( (void*) line[i] );} 但是如果你想将所有行存储到最后,你可能需要更详细的东西。
  • @bastel 我认为你不需要先 malloc 它,只需将 lines 设置为 0,正如 WeatherVane 所注意到的,realloc 可以处理 NULL 并在第一次使用malloc
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多