使用fgets和memcpy将文件读取到char **

时间:2013-05-06 20:03:07

标签: c pointers

我正在尝试从文件到数组读取一组行。我这样做是为了学习malloc和realloc。

#define MAX_LINE 301

char** read_file_lines(char* filename) {
    char** ptr = NULL;
    int max = 5;
    int i = 0;
    FILE *fp = fopen(filename, "r");

    if(fp != NULL) {
        char line[MAX_LINE];
        while(fgets(line, MAX_LINE, fp) != NULL) {

            /* allocate some extra memory for some more lines */
            if(i == max) {
                int new_max = max * 2;
                int nr_bytes = new_max * sizeof(char) * MAX_LINE;
                char **ptr2 = realloc(ptr, nr_bytes);
                if(ptr2 != NULL) {
                    ptr = ptr2;
                    ptr2 = NULL;
                    max = new_max;
                }
            }

            // ptr[i] = line;
            // strcpy(ptr[i], line);
            memcpy(ptr[i], line, strlen(line));
            i++;
        }
        fclose(fp);
    }
    else {
        printf("Error opening file %s\n", filename);
    }

    return ptr;
}

代码编译。但是,执行时会发生错误(程序崩溃)。

我做了一些调试,并确定问题出现在memcpy ()指令中。我以前曾尝试使用strcpy,这也会产生类似的问题。

我去检查memcpy()的protocolo,结果如下:

void * memcpy ( void * destination, const void * source, size_t num );

现在,如果ptrchar**,则ptr[i]不等同于char*吗?

感谢您的评论。

3 个答案:

答案 0 :(得分:3)

看起来ptr未初始化为指向任何内存。此外,您没有为各行分配任何内存。

要初始化ptr,请将声明更改为:

int max = 5;
char** ptr = malloc(max * sizeof(char*));

尝试在调用memcpy之前添加它:

        ptr[i] = malloc(strlen(line) + 1);

并更改realloc来电的计算:

            int nr_bytes = new_max * sizeof(char*);

编辑:要更详细地解释:ptr是指针数组的指针。你必须为ptr分配内存(也就是说,足够的内存只是为了存储单个指针)。 除此之外,您还必须分配ptr的各个元素指向的每个字符数组。

我建议的第一个更改确保ptr始终指向足够的内存来容纳5个指针(或更多,一旦被重新分配。)

第二个更改确保ptr的每个成员在尝试将其作为指针访问之前始终指向有效内存。

第三项更改是必需的,因为ptr指向指针char的元素,而不是char

答案 1 :(得分:1)

问题是,首先没有分配执行内存:i为0,max为5,if条件为false,realloc从未执行。

答案 2 :(得分:1)

罗。数组不是指针。指针的指针不是数组的数组。如果你想要一个二维动态数组,那么你必须为1.指向各行的指针数组分配内存,并为行本身分配内存。