Function that returns pointer crashes when it tries to return pointer to main program

1

I have this function that retrieves a record of a binary file already filled with records - such records are structured as node - and returns it to the program. However, in the return from "i" to the main program variable "test", the two being structured type node , the program stops responding.

I am willing to change any parameter of the function, but I need it to read a node from the binary file and return this node to the main program.

    #include <stdio.h>
    #include <stdlib.h>

typedef struct node 
{
    void ** pointers;
    int * keys;
    struct node * parent;
    bool is_leaf;
    int num_keys;
    struct node * next; 
} node; 

    node* carrega_node (char *nome){   
        FILE * fp;  
        node * i;  
        fp = fopen (nome, "rb");  
        fread (&i, sizeof(node), 1, fp);  
        fclose (fp);  
        return i;  
    };  

    int main()  
    node * teste  

    teste = carrega_node ("candidatos.idx");
    return 0;
    
asked by anonymous 12.12.2014 / 15:45

1 answer

3

There was some confusion with the syntax, this does not make it look like it does. Note:

node* i; // Cria uma variável local do tipo node*. Esse ponteiro aponta para nada

fread(&i, sizeof(node), 1, fp); // Escreve sizeof(node) na variável i. Observe que
                                // i é um ponteiro que tem apenas 4 ou 8 bytes. Mas
                                // sizeof(node) pode ser bem maior que isso. Você
                                // está tentando ler um nodo ou um ponteiro para um nodo?

Here are two problems. The first is that it reads an entire node of the file and writes over the pointer itself to a node. And the second problem is that if you want to read a node, you must first allocate enough memory to store that node. Correction:

node* i = malloc(sizeof(node)); // Aloca memória que caiba um nodo.

fread(i, sizeof(node), 1, fp);  // Lê um nodo e coloca nessa memória.
//    ^ note que estou passando o ponteiro para a memória alocada,
//      não um ponteiro para o ponteiro.

Remember that after you finish using the node, you must free the memory that was allocated using free(i) .

But why did the crash occur? Assume that a pointer has 4 bytes and that a node has 16 bytes.

sizeof(node)   // 16
sizeof(node*)  // 4

When fread(&i, sizeof(node), 1, fp); is executed, the program writes 16 bytes of data to a variable in which 4 bytes fit. The extra 12 bytes will be blindly written into memory corrupting any data that was previously there. Curiously, the information that was there before was the return address of the function. Therefore, the moment you execute return , the execution will skip to another unrelated part of the program, outside the main. And that will cause a crash .

But you have an even more serious problem:

You are saving and reading your file structure. But this structure contains pointers. There is no problem in saving pointers to a file. But they have no useful meaning at all. Because when you load them, in another run of the program, they will be pointing to a memory that has nothing. The memory layout of a process changes completely when it re-executes. And saving the pointer to data is not similar to saving your own data.

It is not directly possible to save a linked list to a file. It needs to first turn into a linear array or something that does not rely on pointers behavior to work.

    
12.12.2014 / 15:56