为什么我在C中使用此代码出现分段错误?

时间:2016-03-15 03:56:34

标签: c file segmentation-fault

我正在尝试从文件中读取一行并返回它,我想迭代地调用此函数,只要我到达EOF或最后一行。这是代码。

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

#define BUFF 100000

int grep_stream(FILE* fpntr, char* string, char* filepathname);
char* get_next_line(FILE* fpntr);
int main()
{
    FILE* fp;
    fp = fopen("movies.txt", "r");
    char* filename = "test";
    char* searchString = "the";
    grep_stream(fp, searchString, filename);
    return 0;               
}
int grep_stream(FILE* fpntr, char* string, char* filepathname)
{

    char* tmp = get_next_line(fpntr);
    char* ret;
    while(tmp != NULL)
    {
        ret = strstr(tmp, string);
        printf("%s\n", ret);
        tmp = get_next_line(fpntr);
    }
    return 0;
}

char* get_next_line(FILE* fpntr)
{
    char buff[BUFF];
    int index = 0;
    int ch = fgetc(fpntr);
    while(ch != '\n' && ch != EOF)
    {
        buff[index++] = ch;
        ch = fgetc(fpntr);
    }
    buff[index] = '\0';
    char* tmp;
    /*I am not freeing this tmp, will that be a problem if I call this function iteratively*/
    tmp = (char*)malloc((int)(index)*sizeof(char));
    strcpy(tmp, buff);
    return tmp;
}

在main中,我将使用有效参数调用grep_stream()函数。

更新: 我要添加的文件是:http://textuploader.com/5ntjm

1 个答案:

答案 0 :(得分:2)

ret = strstr(tmp, string);
printf("%s\n", ret);

这里ret NuLL是否可能?也许你的意思是printf("%s\n", ret ? ret : "NO MATCH");

#define BUFF 100000
char buff[BUFF];

这是一个巨大的数组。可能导致堆栈溢出?

char buff[BUFF];
int index = 0;
int ch = fgetc(fpntr);
while(ch != '\n' && ch != EOF)
{
    buff[index++] = ch;
    ch = fgetc(fpntr);
}

如果用户输入的行太长,则会溢出buff数组。您是否考虑过在该循环上设置上限?

tmp = (char*)malloc((int)(index)*sizeof(char));
strcpy(tmp, buff);

这里有太多的施法(应该没有),malloc接受size_t(不是int),而sizeof char始终为1。请注意,index当然应该是size_t

字符串最后占用'\0'的附加字符。您无法为该附加字符分配空间,因此strcpy将溢出缓冲区。

不要忘记检查malloc的返回值。你可能想写:

tmp = malloc(index + 1);
if (tmp == NULL) {
    return NULL;
}
strcpy(tmp, buff);

malloc的返回值类似,您需要检查fopen的返回值:

fp = fopen("movies.txt", "r");
if (fp == NULL) {
    puts("Error opening movies.txt");
    exit(EXIT_FAILURE);
}

最后一点,malloc应为free'的所有内容。您当前的算法会泄漏大量内存。如果文件足够大,这可能会导致程序崩溃。