函数mallocs指针并将数据读入其中,但调用者无法访问它

时间:2014-12-27 23:51:16

标签: c windows file pointers

我有一个特定的问题:当我尝试使用自己的函数在内存中加载文件时,我遇到了问题。

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);
}

4 个答案:

答案 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_destinybuffer_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。