2014-02-16 3 views
0

Я в настоящее время занимаюсь некоторыми работами в университете на C + (действительно C, просто меняйте malloc и бесплатно для новых и удаляйте). Проблема заключается в том, что компилятор освобождает память, выделенную в функции, хотя указатель указывает на это пространство памяти, вызывая сбои сегментации при попытке доступа к указанному полю структур. (Упрощенный пример) Код ниже:C++ (компилятор?) Освобождение памяти выделено в функции

P.S .: Я компилирую стандарт C++ 2003 с -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; 
} 
+0

программирования C с C++. Вы должны узнать о конструкторах, классах и объектах. Это упростит ситуацию. – Matt

ответ

3

Это не работает, потому что вы передаете указатель по значению. Это означает, что внутри InsertarUsuarioвы просто устанавливаете локальную переменную baseDatos в память, выделенную new, не давая при этом ничего полезного для вызывающего.

Вы хотите выделить память в вызываемой функции и иметь возможность ссылаться на выделенный объект от вызывающего. Для этого вам нужно передать указатель самим addres. Таким образом, вы передаете указатель на указатель на Usuario. Что-то вроде:

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; 
    .. 
} 
0

Компилятор не освобождает память: вы просто никогда не изменить значение baseDatos. InsertarUsuario получает экземпляр значения указателя (изначально NULL) и локально меняет его, но изменения в прямом значении аргумента не отражаются в вызывающей функции. Это означает, что как только InsertarUsuario вернется, baseDatos снова NULL.

Вам необходимо либо вернуть baseDatos из InsertarUsuario (и прекратить прием его в качестве параметра), или принимать указатель на указатель Usuarioдвойного указателя) или ссылки на этот указатель.

0

Вы передаете baseDatos в InsertarUsuario по значению, а не ссылаться (или указатель на указатель), поэтому ее значение в функции RegistrarUsuario не меняется.

Попробуйте изменить прототип InsertarUsuario к

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

и называют его

InsertarUsuario(&baseDatos, AuxCorreo, AuxNombre, AuxDNI, aux); 
Смежные вопросы