我有一个特定的问题:当我尝试使用自己的函数在内存中加载文件时,我遇到了问题。
load_file_on_memory()
收到文件名和指针。它只是打开文件,为文件内容动态分配内存并填充它,并使用destiny
作为参数将指针传递给调用者。
但我遇到了一个问题:在load_file_on_memory()
内部功能,我在malloc
空间内取得了成功。我可以将数据放在指针上并获取它。
当我尝试使用指针外部函数时,调用者只是垃圾。我将在这里发布我的代码。
我无法理解为什么会这样。我使用Windows 7与Tiny C编译器。我不知道那个环境是否会导致错误。
这是我的来源
#include <stdio.h>
#include <stdlib.h>
int load_file_on_buffer(char filename[], void *buffer_destiny){
FILE *file_loaded;
unsigned int file_size;
file_loaded = fopen(filename, "rb");
if(file_loaded == NULL)
return -1;
fseek(file_loaded, 0, SEEK_END);
file_size = ftell(file_loaded);
fseek(file_loaded, 0, SEEK_SET);
buffer_destiny = (void *) malloc(file_size);
fread((char *) buffer_destiny, file_size, 1, file_loaded);
printf("BEGIN DEBUG FILE\n");
printf("%s", buffer_destiny);
printf("\n\nEND DEBUG FILE\n");
fclose(file_loaded);
return 0;
}
int main(int argc, char *argv[]){
char *buffered_input_file;
///First, load input file
if(load_file_on_buffer("test.txt", (void *)buffered_input_file) != 0)
return -1;
printf("Input file loaded successfully\n");
printf("This function must print file content: \n\n");
printf("%s", buffered_input_file);
}
答案 0 :(得分:4)
您正在传递参数void * buffer_destiny。输入函数后,这只是一个普通变量。使用malloc()调用覆盖的内容。这对调用函数没有影响。而是将函数声明为
int load_file_on_buffer(char filename[], void **pbuffer_destiny)
将其称为
void* buffered_input_file;
load_file_on_buffer("test.txt", &buffered_input_file)
并在函数中写入
void* buffer_destiny = malloc (...);
*pbuffer_destiny = buffer_destiny;
答案 1 :(得分:3)
指针buffer_destiny
是函数load_file_on_buffer
中的局部变量。更改buffer_destiny
对buffer_input_file
中的指针main
没有影响。解决问题的一种方法是return
指向main
的指针。
另一个问题是您使用"%s"
打印文件内容。为了使其工作,您需要正确NUL终止缓冲区。换句话说,缓冲区需要比文件大小大一个字节,并且需要将NUL终结符'\0'
放在该额外字节中。
#include <stdio.h>
#include <stdlib.h>
char *load_file_on_buffer( const char *filename )
{
FILE *file_loaded;
unsigned int file_size;
file_loaded = fopen(filename, "rb");
if(file_loaded == NULL)
return NULL;
fseek(file_loaded, 0, SEEK_END);
file_size = ftell(file_loaded);
fseek(file_loaded, 0, SEEK_SET);
char *buffer_destiny = malloc(file_size + 1);
fread( buffer_destiny, file_size, 1, file_loaded );
buffer_destiny[file_size] = '\0';
printf("BEGIN DEBUG FILE\n");
printf("%s", buffer_destiny);
printf("\n\nEND DEBUG FILE\n");
fclose(file_loaded);
return buffer_destiny;
}
int main(int argc, char *argv[])
{
char *buffered_input_file;
///First, load input file
if( (buffered_input_file = load_file_on_buffer("test.txt")) == NULL )
return -1;
printf("Input file loaded successfully\n");
printf("This function must print file content: \n\n");
printf("%s", buffered_input_file);
}
答案 2 :(得分:2)
如果您仍想将buffered_input_file
作为参数传递,那么这对您有用,我在某些部分对代码进行了评论,我认为需要澄清。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int load_file_on_buffer(char filename[], void **buffer_destiny)
{
FILE *file_loaded;
unsigned int file_size;
if (buffer_destiny == NULL)
return -1;
*buffer_destiny = NULL; /* to check in the calling function */
file_loaded = fopen(filename, "r"); /* rb is no longer needed in new code */
if(file_loaded == NULL)
return -1;
fseek(file_loaded, 0, SEEK_END);
file_size = ftell(file_loaded);
fseek(file_loaded, 0, SEEK_SET);
*buffer_destiny = malloc(1 + file_size); /* +1 for the null terminator */
if (*buffer_destiny == NULL)
{
fclose(file_loaded);
return -1;
}
/* add a null terminator so the string is acceptable by printf */
memset(*buffer_destiny + file_size, '\0', 1);
/* you got this wrong
*
* fread((char *) buffer_destiny, file_size, 1, file_loaded);
*
* the correct way is
*
* fread(void *ptr, size_t size, size_t count, FILE *fp);
*
* where size is the size of each element and count is the number of elements.
*/
if (fread(*buffer_destiny, 1, file_size, file_loaded) != file_size)
{
free(*buffer_destiny);
*buffer_destiny = NULL;
fclose(file_loaded);
return -1;
}
printf("BEGIN DEBUG FILE\n");
printf("%s", (char *)*buffer_destiny);
printf("END DEBUG FILE\n");
fclose(file_loaded);
return 0;
}
int main(int argc, char *argv[])
{
char *buffered_input_file;
if (load_file_on_buffer("data.dat", (void **)&buffered_input_file) != 0)
return -1;
printf("Input file loaded successfully\n");
printf("This function must print file content: \n\n");
printf("%s", buffered_input_file);
free(buffered_input_file);
return 0;
}
答案 3 :(得分:0)
buffered_input_file最初在main()中为NULL,并按值传递给load_file_on_buffer()。 buffer_destiny最初从main()获得NULL但在内存分配后内部函数它应该正如你提到的那样正常运行。但是,buffer_destiny是一个局部变量而不是传递变量的指针,因此在函数结束时它会丢失其信息,而main()中的buffered_input_file仍为NULL。