动态读取和存储到char数组

时间:2013-10-01 08:33:07

标签: c arrays segmentation-fault malloc

我有一个我想要读取的文件并将数据存储到char数组中,我在每个字符读取后动态分配内存。我想动态地将内存精确地分配给所需大小的内存。这就是我所拥有的:

FILE *fp;
char *data;
int c=0;

fp=fopen("home/bob/Downloads/filename", "r");
data=malloc(sizeof(char));

do{
    data[c]=fgetc(fp);
    printf("data : %c\n", data[c]);
    c++;
    data=realloc(data, sizeof(char)+c);
} while(data[c]!=EOF);

我遇到了分段错误。

6 个答案:

答案 0 :(得分:2)

问题很可能在这里:

while(data[c]!=EOF)

请记住,你在循环中增加 c,因此data[c]是你分配的内存的未初始化部分。这意味着只要未初始化的数据不是(char) -1,您将继续逐个字符地读取,这可能远远超出文件的实际结束。

而是尝试这样的事情:

char *data = NULL;
size_t c = 0;

for (;;)
{
    const int ch = fgets(fp);
    if (ch == EOF)
        break;  /* Error or end of file */

    char *tmp = realloc(data, c + 1);
    if (tmp == NULL)
        break;  /* Could not allocate memory */

    data = tmp;
    data[c++] = ch;
}

答案 1 :(得分:1)

当您的程序尝试评估以下条件时:

(data[c]!=EOF)

c已经增加,data[c]因此尝试访问data数组范围之外的元素,导致 未定义的行为

答案 2 :(得分:1)

首先,您必须使用带有malloc coz malloc的类型转换返回void *

data=(char*)malloc(sizeof(char));

此外,EOF不是字符(EOF = -1)

while循环内的条件指向一个尚未初始化的内存部分。

int ch;
while(1)
{
if( (ch=fgets(fp))==EOF )
    break;
data[c]=ch;
c++;
data=realloc(data, sizeof(char)+c);
}

答案 3 :(得分:0)

您已分配一个字节的内存。这绝对不足以读取文件。

我建议使用stat()解释How do you determine the size of a file in C?来获取大小,然后分配size*sizeof(char)

#include <sys/stat.h>

off_t fsize(const char *filename) {
    struct stat st; 

    if (stat(filename, &st) == 0)
        return st.st_size;

    return -1; 
}

{
    FILE *fp;
    char *data;
    int c=0;
    off_t size = fsize("home/bob/Downloads/filename") +1;

    fp=fopen("home/bob/Downloads/filename", "r");
    data=malloc(sizeof(char) * size);

    do{
        data[c]=fgetc(fp);
        printf("data : %c\n", data[c]);
        c++;
        data=realloc(data, sizeof(char)+c);
    }while(data[c]!=EOF);
}

答案 4 :(得分:0)

do{
    data[c]=fgetc(fp);
    printf("data : %c\n", data[c]);
    c++;
    data=realloc(data, sizeof(char)+c);
}while(data[c]!=EOF);  // this should be the location of the seg fault

虽然(data [c])看起来在数组的末尾。

待办事项

}while(data[c - 1]!=EOF);

或在检查后增加c

答案 5 :(得分:0)

data[c]=fgetc(fp);  --> This gives seg fault 

因为您正在增加c++

data=malloc(sizeof(char));
data然后sizeof(char)成为UB时,

c++指向data[c]的记忆。