传递给为其分配内存的函数的指针仅在指针 NULL 初始化时有效
Pointer passed to function which allocates memory to it only works if pointer NULL intialized
我正在编写一个将文件读入内存的函数,遇到了一个奇怪的问题。如果在将返回的指针传递给函数之前将其初始化为 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);
}
如果main函数中的变量'fdata'没有初始化为NULL,程序运行失败,输出如下:
read 2599298 bytes.
Segmentation fault (core dumped)
但是,如果它被初始化为 NULL,那么它显然会按预期运行并输出以下内容:
read 2599298 bytes.
我试过用gdb调试这个程序,段错误发生在main函数末尾的free()调用处。任何帮助将不胜感激。
提前致谢,
瓦拉德
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);
我正在编写一个将文件读入内存的函数,遇到了一个奇怪的问题。如果在将返回的指针传递给函数之前将其初始化为 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);
}
如果main函数中的变量'fdata'没有初始化为NULL,程序运行失败,输出如下:
read 2599298 bytes.
Segmentation fault (core dumped)
但是,如果它被初始化为 NULL,那么它显然会按预期运行并输出以下内容:
read 2599298 bytes.
我试过用gdb调试这个程序,段错误发生在main函数末尾的free()调用处。任何帮助将不胜感激。
提前致谢, 瓦拉德
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);