我正在编写一个将文件读取到内存中的函数,遇到了一个奇怪的问题。只有在将返回的指针传递给函数之前将其初始化为NULL,才能成功地返回free((。这是代码,
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
ssize_t
file_size(const char *path)
{
struct stat stats;
if (stat(path, &stats))
return (-1);
return (stats.st_size);
}
ssize_t
read_file(const char *path, char *data)
{
data = NULL;
FILE *fp;
ssize_t tmp;
size_t fl;
tmp = file_size(path);
if (tmp < 0) goto err;
fl = (size_t)tmp;
data = malloc(fl);
if (data == NULL) goto err;
fp = fopen(path, "rb");
if (fp == NULL) goto err;
if (fread(data, 1L, fl, fp) != fl) goto err;
if (ferror(fp)) goto err;
fclose(fp);
return (fl);
err:
if (fp)
{
int errno_save = errno;
fclose(fp);
errno = errno_save;
}
free(data);
return (-1);
}
int
main(void)
{
char *fdata; // If this is initialized to NULL, then the program works fine
size_t fdata_len;
fdata_len = read_file("/home/varad/wallpaper.jpg", fdata);
printf("read %zu bytes.n", fdata_len);
free(fdata); // Segfault happens over here
return (0);
}
如果主函数中的变量"fdata"未初始化为NULL,则程序将失败,并输出以下内容:
read 2599298 bytes.
Segmentation fault (core dumped)
然而,如果它被初始化为NULL,那么它显然会按照预期运行,并输出以下内容:
read 2599298 bytes.
我试着用gdb调试这个程序,但分段错误发生在主函数末尾的free((调用处。任何帮助都将不胜感激。
提前感谢,Varad
read_file(const char *path, char *data)
data
是一个局部变量。您所做的更改只是此函数的本地更改。您需要将引用传递给指针。
ssize_t
read_file(const char *path, char **data)
{
FILE *fp = NULL;
ssize_t tmp;
size_t fl;
if(!data) goto err;
tmp = file_size(path);
if (tmp < 0) goto err;
fl = (size_t)tmp;
*data = malloc(fl);
if (*data == NULL) goto err;
fp = fopen(path, "rb");
if (fp == NULL) goto err;
if (fread(*data, 1L, fl, fp) != fl) goto err;
if (ferror(fp)) goto err;
fclose(fp);
return (fl);
err:
if (fp)
{
int errno_save = errno;
fclose(fp);
errno = errno_save;
}
if(data) free(*data);
return (-1);
}
并相应地调用:
fdata_len = read_file("/home/varad/wallpaper.jpg", &fdata);