今天我正在尝试编写程序,我意识到我需要在程序中的更多位置读取一个文件,但在我到达之前我有以下内容:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *printFile(char *fileName){
long int length;
char *buffer;
size_t size;
FILE *file;
file = fopen (fileName , "r" );
fseek (file , 0 , SEEK_END);
length = ftell (file);
fseek (file , 0 , SEEK_SET);
buffer = (char *) malloc (sizeof(char)*(size_t)length);
if (buffer == NULL){
fputs ("Memory error",stderr);
exit (2);
}
size = fread (buffer,1,(size_t) length,file);
if (size != (size_t)length){
fputs ("Reading error",stderr);
exit(3);
}
fclose (file);
return buffer;
}
int main (void) {
char *fileName = "test.txt";
char *fileContent = printFile(fileName);
printf("%s", fileContent);
free(fileContent);
return 0;
}
正如你所看到我在main函数中使用了free,在我意识到我的程序不行之后我决定在printFile函数中释放缓冲区,现在我有了这个:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *printFile(char *fileName){
long int length;
char *buffer,*buffer2;
size_t size;
FILE *file;
file = fopen (fileName , "r" );
if (file == NULL){
fputs ("File error",stderr);
fclose (file);
exit (1);
}
fseek (file , 0 , SEEK_END);
length = ftell (file);
fseek (file , 0 , SEEK_SET);
buffer = (char *) malloc (sizeof(char)*(size_t)length);
if (buffer == NULL){
fputs ("Memory error",stderr);
exit (2);
}
buffer2 = (char *) malloc (sizeof(char)*(size_t)length);
if (buffer2 == NULL){
fputs ("Memory error",stderr);
exit (2);
}
size = fread (buffer,1,(size_t) length,file);
if (size != (size_t)length){
fputs ("Reading error",stderr);
exit(3);
}
strcpy (buffer2, buffer);
fclose (file);
free(buffer);
return buffer2;
}
int main (void) {
char *fileName = "test.txt";
char *fileContent = printFile(fileName);
printf("%s", fileContent);
return 0;
}
正如您可能已经注意到我使用了第二个指针(* buffer2)来复制其中第一个缓冲区的内容,然后将其释放到第一个缓冲区中。
我的问题是: 我的做法是对还是错?
答案 0 :(得分:1)
欢迎使用内存管理!
你应该问的问题是:为什么你的第二种方法优于前者?您可以免费buffer
,然后返回buffer2
,有人必须释放buffer2
,因此您处于与以前完全相同的位置,除非您复制了两次文件内容。 / p>
如果您不想在printFile()
内分配内存,请强制调用者传入缓冲区。换句话说,将处理分配的责任转移到使用printFile()
的任何代码。当然,现在调用者不得不担心分配足够大的缓冲区(尽管使用stat(2)
很容易获得文件大小,或者像你一样使用stdio包装器)。
无论你最终使用什么方法,当你开始使用动态分配时,你就无法逃避内存管理:某个人必须负责释放内存。
答案 1 :(得分:1)
您的方法可以改进。
而不是
char *printFile(char *fileName);
使用两个功能
char *getFileContents(char *fileName);
void printFile(char *fileName);
理解getFileContents
返回函数用户需要free
d的内存。 printFile()
和其他功能可以调用getFileContents()
,可以随意调用内容,然后在内存中调用free()
。
此外,如果在阅读文件内容时出错,请返回NULL
,而不是致电exit()
。
char *getFileContents(char *fileName)
{
long int length;
char *buffer;
size_t size;
FILE *file;
file = fopen (fileName , "r" );
if (file == NULL){
fputs ("File error",stderr);
return NULL;
}
fseek (file , 0 , SEEK_END);
length = ftell (file);
fseek (file , 0 , SEEK_SET);
buffer = (char *) malloc (sizeof(char)*(size_t)length);
if (buffer == NULL){
fclose (file);
fputs ("Memory error",stderr);
return NULL;
}
size = fread (buffer,1,(size_t) length,file);
if (size != (size_t)length){
fputs ("Reading error",stderr);
fclose (file);
return NULL;
}
fclose (file);
return buffer;
}
char *printFile(char *fileName)
{
char* fileContents = getFileContents(fileName);
if ( NULL != fileContents )
{
printf("%s", fileContents);
free(fileContents);
}
}