简体   繁体   中英

C++ (compiler?) freeing memory allocated in function

I am currently doing some University work in C+ (really C, just swap malloc and free for new and delete). The problem is that compiler deallcoates memory allocated in a function, even though a pointer is pointing to that memory space, causing a segmentation fault when trying to access said structures field. (Simplified example) Code below:

PS: I am compiling to C++ 2003 standard with -Og.

main.cpp:

#include <cstdlib>
#include <iostream>
#include <cstring>

using namespace std;

struct Usu{
   long unsigned int  DNI;
   char Correo[30];
   char Nombre[30];
   char Foto[20][20];
   char *publicaciones;
   long unsigned int *amigos;
   struct Usu *next;
};

typedef struct Usu Usuario;

void RegistrarU(Usuario *);
void InsertarUsuario(Usuario *, char *, char *, long unsigned int, Usuario *);

int main (int argc, char *argv[]) {
   Usuario * baseDatos = NULL;
   RegistrarU(baseDatos);
}

void RegistrarU(Usuario * baseDatos)
{
   long unsigned int AuxDNI = 34212345;
   char AuxNombre[30] = "Hello";
   char AuxCorreo[30]= "World";
   Usuario *aux = NULL;
   InsertarUsuario(baseDatos, AuxCorreo, AuxNombre, AuxDNI, aux);
   cout<<baseDatos->DNI; //Doesn't work here
   system("pause");
}

void InsertarUsuario(Usuario * baseDatos , char * AuxCorreo,char * AuxNombre,long unsigned int AuxDNI, Usuario * aux)
{ 
       baseDatos = new Usuario;
       baseDatos->DNI = AuxDNI;
       strcpy(baseDatos->Nombre,AuxNombre);
       strcpy(baseDatos->Correo,AuxCorreo);
       baseDatos->next = NULL;
       cout<<baseDatos->DNI; //Works Here
       system("pause");

       return;
}

It doesn't not work because you are passing a pointer by value. This means that inside InsertarUsuario you are just setting the local variable baseDatos to the memory allocated by new , without effectively giving anything useful to the caller.

You want to allocate memory in the called function and be able to reference the allocated object from the caller. To do this you need to pass the pointer by addres itself. So you pass a pointer to a pointer to a Usuario . Something like:

Usuario * baseDatos = NULL;
RegistrarU(&baseDatos);

void RegistrarU(Usuario ** baseDatos) { 
  ..
  InsertarUsuario(baseDatos, AuxCorreo, AuxNombre, AuxDNI, aux);
}

void InsertarUsuario(Usuario ** baseDatos , char * AuxCorreo,char * AuxNombre,long unsigned int AuxDNI, Usuario * aux) {
  Usuario *tmpUsuario = new Usuario;
  *baseDatos = tmpUsuario;
  ..
}

The compiler doesn't free memory: you simply never change the value of baseDatos . InsertarUsuario receives a copy of the pointer value (initially NULL ) and locally changes it, but changes to the straight-up value of an argument aren't reflected in the calling function. This means that once InsertarUsuario returns, baseDatos is NULL again.

You either need to return baseDatos from InsertarUsuario (and stop accepting it as a parameter), or accept a pointer to the Usuario pointer (a double pointer ) or a reference to that pointer.

You are passing baseDatos into InsertarUsuario by value, not reference (or pointer to pointer), so its value in the RegistrarUsuario function is not changing.

Try changing the prototype of InsertarUsuario to

void InsertarUsuario(Usuario ** baseDatos , char * AuxCorreo,char * AuxNombre,long unsigned int AuxDNI, Usuario * aux)

and call it as

   InsertarUsuario(&baseDatos, AuxCorreo, AuxNombre, AuxDNI, aux);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM