如何解决C程序引发打开文件的Malloc错误?

时间:2018-04-02 21:32:58

标签: c file io malloc

我有一个程序来逐行读取文件(在argv中作为参数给出)并将其输出到另一个文件。这是代码;

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

#define CAT_PREFIX_LEN    4
#define CAT_PREFIX        "bsh_"

int main(int argc, char** argv) {
    FILE *toread, *towrite;
    char *line;
    size_t len = 0;
    ssize_t read;

    char catfile[CAT_PREFIX_LEN + strlen(argv[1]) + 1];

    // Opening file to read
    toread = fopen(argv[1], "r");

    // Create output file name
    strcpy(catfile, CAT_PREFIX);
    strcat(catfile, argv[1]);

    // Opening file to write
    towrite = fopen(catfile, "w");

    while((read = getline(&line, &len, toread)) != -1) {
        fprintf(towrite, line);
    }

    fclose(toread);
    fclose(towrite);
}

但是,如果我尝试使用测试文件test.txt运行此程序,则会收到错误消息: convert_script(21115,0x7fffcb3f43c0) malloc: *** error for object 0x10caca4c0: pointer being realloc'd was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap: 6

我尝试过多种方法;我尝试的第一件事是评论整个for循环。如果我注释掉整个for循环,那么错误就会消失。我也尝试删除开头,关闭并写入test.txt。如果我删除它,错误也会消失。我真的不知道是什么原因造成的。我在MacBook Air上运行它并使用gcc编译它来编译它。

1 个答案:

答案 0 :(得分:1)

char *line;

未初始化且包含不确定的值。

Linux getline() man page

  

如果*lineptr设置为NULL并且*n在通话前设置为0,那么          getline()将分配一个缓冲区来存储该行。这个缓冲区          即使getline()失败,也应该被用户程序释放。

由于您使用的是Mac,the POSIX getline() standard会添加:

  

应用程序应确保*lineptr是可以传递给free()函数的有效参数。如果*n非零,   申请应确保*lineptr指向一个   大小至少为*n个字节的对象,或者是一个空指针。

要严格遵守POSIX标准,您应该将line初始化为NULL

char *line = NULL;

编辑:官方Apple getline() man page声明:

  

调用者可以为该行提供指向malloced缓冲区的指针   *linep,以及它的能力        *linecapp中的缓冲区。这些函数根据需要扩展缓冲区,就像通过realloc()一样。如果linep        指向NULL指针,将分配一个新的缓冲区。在任何一种情况下,都会*linep*linecapp        相应更新。