C - realloc() 指针然后在函数内部设置值
C - realloc() pointer then set value inside function
我正在尝试用 C 编写一个函数,将文件读入传递给它的 char 数组。
void read_file(char* path, char** bufptr, char* buffer){
/* open the file, and exit on errors */
FILE *fp = fopen(path, "r");
if(fp == NULL){
perror("Failed to open file");
exit(1);
}
/* figure out how long the file is to allocate that memory */
fseek(fp, 0, SEEK_END);
long length = ftell(fp);
rewind(fp);
/* allocate memory */
*bufptr = realloc(*bufptr, length+1);
fread(buffer, length, 1, fp);
buffer[length] = 0;
}
我的想法是我会像这样使用它:
int main(int argc, char** argv){
char* somestring = malloc(1024);
core_read_file("/some/file/path", &somestring, somestring);
printf("In main(): %s\n", somestring);
free(somestring);
return 0;
}
然而,每当我使用它时,当程序编译时,printf 不会向控制台打印任何内容。我刚开始,有点理解 "indirection" 的概念到非常非常基本的程度,但是有人可以向我解释为什么我的代码不能按我期望的方式工作,以及我应该如何去做实现这个功能。
(这不是家庭作业,所以任何有效的解决方案或方法都是完美的)
read_file
的最后两行应该是:
fread(*bufptr, length, 1, fp);
(*bufptr)[length] = 0;
新分配的缓冲区中的指针在*bufptr
中,而不是在buffer
中。
但是你的程序过于复杂,你不需要传递三个参数呢read_file
。两个就够了,像这样:
void read_file(char* path, char** bufptr) {
/* open the file, and exit on errors */
FILE *fp = fopen(path, "r");
if (fp == NULL) {
perror("Failed to open file");
exit(1);
}
/* figure out how long the file is to allocate that memory */
fseek(fp, 0, SEEK_END);
long length = ftell(fp);
rewind(fp);
/* allocate memory */
*bufptr = realloc(*bufptr, length + 1);
fread(*bufptr, length, 1, fp);
(*bufptr)[length] = 0;
}
int main(int argc, char** argv) {
char* somestring = malloc(1024); // char* somestring = NULL would be even better here
read_file("readme.txt", &somestring);
printf("In main(): %s\n", somestring);
free(somestring);
return 0;
}
为简洁起见,这里仍然没有对 realloc
进行错误检查。
如果您打算在函数内部分配内存 - 则无需在外部分配。但是应该有记录的协议 - 在失败的情况下 - 没有任何东西未释放,在成功的情况下 - 调用函数负责释放缓冲区指针。
您的读取功能必须进行更多的错误检查,并且还必须关闭任何分支上的文件。
下面是读取的示例代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
long read_file(const char* path, char** bufptr) {
char* buffer;
int res;
size_t read;
FILE *fp;
if (path == NULL || bufptr == NULL) {
perror("Invalid parameters");
return -6;
}
/* open the file, and exit on errors */
fp = fopen(path, "rb");
if (fp == NULL) {
perror("Failed to open file");
return -1;
}
/* figure out how long the file is to allocate that memory */
res = fseek(fp, 0, SEEK_END);
if (res != 0) {
perror("Failed to seek file");
fclose(fp);
return -2;
}
long length = ftell(fp);
if (length <= 0) {
perror("Failed ftell");
fclose(fp);
return -3;
}
rewind(fp);
/* allocate memory */
buffer = malloc(length + 1);
if (buffer == NULL) {
perror("Out of memory");
fclose(fp);
return -4;
}
read = fread(buffer, 1, length, fp);
fclose(fp);
if ((long)read != length) {
perror("Failed to read whole file");
free(buffer);
return -5;
}
buffer[length] = 0;
*bufptr = buffer;
return length;
}
int main() {
char* somestring;
long res = read_file("c:/key.txt", &somestring);
if (res < 0) {
//nothing is leaked - everything opened or allocated was closed and freed by the function
exit(res);
}
printf("In main(): %s\n", somestring);
free(somestring);
return 0;
}
我正在尝试用 C 编写一个函数,将文件读入传递给它的 char 数组。
void read_file(char* path, char** bufptr, char* buffer){
/* open the file, and exit on errors */
FILE *fp = fopen(path, "r");
if(fp == NULL){
perror("Failed to open file");
exit(1);
}
/* figure out how long the file is to allocate that memory */
fseek(fp, 0, SEEK_END);
long length = ftell(fp);
rewind(fp);
/* allocate memory */
*bufptr = realloc(*bufptr, length+1);
fread(buffer, length, 1, fp);
buffer[length] = 0;
}
我的想法是我会像这样使用它:
int main(int argc, char** argv){
char* somestring = malloc(1024);
core_read_file("/some/file/path", &somestring, somestring);
printf("In main(): %s\n", somestring);
free(somestring);
return 0;
}
然而,每当我使用它时,当程序编译时,printf 不会向控制台打印任何内容。我刚开始,有点理解 "indirection" 的概念到非常非常基本的程度,但是有人可以向我解释为什么我的代码不能按我期望的方式工作,以及我应该如何去做实现这个功能。
(这不是家庭作业,所以任何有效的解决方案或方法都是完美的)
read_file
的最后两行应该是:
fread(*bufptr, length, 1, fp);
(*bufptr)[length] = 0;
新分配的缓冲区中的指针在*bufptr
中,而不是在buffer
中。
但是你的程序过于复杂,你不需要传递三个参数呢read_file
。两个就够了,像这样:
void read_file(char* path, char** bufptr) {
/* open the file, and exit on errors */
FILE *fp = fopen(path, "r");
if (fp == NULL) {
perror("Failed to open file");
exit(1);
}
/* figure out how long the file is to allocate that memory */
fseek(fp, 0, SEEK_END);
long length = ftell(fp);
rewind(fp);
/* allocate memory */
*bufptr = realloc(*bufptr, length + 1);
fread(*bufptr, length, 1, fp);
(*bufptr)[length] = 0;
}
int main(int argc, char** argv) {
char* somestring = malloc(1024); // char* somestring = NULL would be even better here
read_file("readme.txt", &somestring);
printf("In main(): %s\n", somestring);
free(somestring);
return 0;
}
为简洁起见,这里仍然没有对 realloc
进行错误检查。
如果您打算在函数内部分配内存 - 则无需在外部分配。但是应该有记录的协议 - 在失败的情况下 - 没有任何东西未释放,在成功的情况下 - 调用函数负责释放缓冲区指针。
您的读取功能必须进行更多的错误检查,并且还必须关闭任何分支上的文件。
下面是读取的示例代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
long read_file(const char* path, char** bufptr) {
char* buffer;
int res;
size_t read;
FILE *fp;
if (path == NULL || bufptr == NULL) {
perror("Invalid parameters");
return -6;
}
/* open the file, and exit on errors */
fp = fopen(path, "rb");
if (fp == NULL) {
perror("Failed to open file");
return -1;
}
/* figure out how long the file is to allocate that memory */
res = fseek(fp, 0, SEEK_END);
if (res != 0) {
perror("Failed to seek file");
fclose(fp);
return -2;
}
long length = ftell(fp);
if (length <= 0) {
perror("Failed ftell");
fclose(fp);
return -3;
}
rewind(fp);
/* allocate memory */
buffer = malloc(length + 1);
if (buffer == NULL) {
perror("Out of memory");
fclose(fp);
return -4;
}
read = fread(buffer, 1, length, fp);
fclose(fp);
if ((long)read != length) {
perror("Failed to read whole file");
free(buffer);
return -5;
}
buffer[length] = 0;
*bufptr = buffer;
return length;
}
int main() {
char* somestring;
long res = read_file("c:/key.txt", &somestring);
if (res < 0) {
//nothing is leaked - everything opened or allocated was closed and freed by the function
exit(res);
}
printf("In main(): %s\n", somestring);
free(somestring);
return 0;
}