DiegoEmilio01 / IIC3413

Repositorio del curso Implementación de Sistemas de Bases de Datos
16 stars 2 forks source link

Error Manejo de Memoria al crear un array #14

Open sebaterrazas opened 3 months ago

sebaterrazas commented 3 months ago

Hola, he estado atascado en cómo implementar la función vacuum. Entiendo lo que hay que hacer, y creo tener todo listo, pero no he podido hacer una lista de Record, en el cual guardo los Record que deben estar presentes en la nueva página. Sin querer mostrar mucho mi código por aquí, básicamente creo una lista auxiliar std::vector<Record> array; en la cuál voy agregando los Records pertinentes array.push_back(record);. Mi problema es que después del segundo record que agrego (el primero se agrega bien), me salta este error:

(base) sebaterrazas@Sebastians-MacBook-Pro IIC3413 % ./build/Debug/tests/test_example_4 > output.out
=================================================================
==93216==ERROR: AddressSanitizer: attempting double-free on 0x000146403d80 in thread T0:
    #0 0x102da98ac in wrap__ZdaPv+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x518ac) (BuildId: f0a7ac5c49bc3abc851181b6f92b308a32000000200000000100000000000b00)
    #1 0x102871ac4 in Record::~Record() record.cc:35
    #2 0x102871e08 in Record::~Record() record.cc:26
    #3 0x1028b9c10 in std::__1::allocator<Record>::destroy[abi:v15006](Record*) allocator.h:170
    #4 0x1028b9b74 in void std::__1::allocator_traits<std::__1::allocator<Record>>::destroy[abi:v15006]<Record, void>(std::__1::allocator<Record>&, Record*) allocator_traits.h:309
    #5 0x1028c1b0c in std::__1::__split_buffer<Record, std::__1::allocator<Record>&>::__destruct_at_end[abi:v15006](Record*, std::__1::integral_constant<bool, false>) __split_buffer:296
    #6 0x1028c1900 in std::__1::__split_buffer<Record, std::__1::allocator<Record>&>::__destruct_at_end[abi:v15006](Record*) __split_buffer:137
    #7 0x1028c1748 in std::__1::__split_buffer<Record, std::__1::allocator<Record>&>::clear[abi:v15006]() __split_buffer:95
    #8 0x1028c15ac in std::__1::__split_buffer<Record, std::__1::allocator<Record>&>::~__split_buffer() __split_buffer:353
    #9 0x1028bce38 in std::__1::__split_buffer<Record, std::__1::allocator<Record>&>::~__split_buffer() __split_buffer:352
    #10 0x1028bab7c in void std::__1::vector<Record, std::__1::allocator<Record>>::__push_back_slow_path<Record const&>(Record const&) vector:1540
    #11 0x1028b50d4 in std::__1::vector<Record, std::__1::allocator<Record>>::push_back[abi:v15006](Record const&) vector:1553
    #12 0x1028b4204 in HeapFilePage::vacuum(Schema const&) heap_file_page.cc:134
    #13 0x1028aa520 in HeapFile::vacuum() heap_file.cc:51
    #14 0x10280628c in main test_example_4.cc:50
    #15 0x18e7f3f24  (<unknown module>)

0x000146403d80 is located 0 bytes inside of 256-byte region [0x000146403d80,0x000146403e80)
freed by thread T0 here:
    #0 0x102da98ac in wrap__ZdaPv+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x518ac) (BuildId: f0a7ac5c49bc3abc851181b6f92b308a32000000200000000100000000000b00)
    #1 0x102871ac4 in Record::~Record() record.cc:35
    #2 0x102871e08 in Record::~Record() record.cc:26
    #3 0x1028b4210 in HeapFilePage::vacuum(Schema const&) heap_file_page.cc:135
    #4 0x1028aa520 in HeapFile::vacuum() heap_file.cc:51
    #5 0x10280628c in main test_example_4.cc:50
    #6 0x18e7f3f24  (<unknown module>)

previously allocated by thread T0 here:
    #0 0x102da9498 in wrap__Znam+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x51498) (BuildId: f0a7ac5c49bc3abc851181b6f92b308a32000000200000000100000000000b00)
    #1 0x102870644 in Record::Record(std::__1::vector<DataType, std::__1::allocator<DataType>>&&) record.cc:16
    #2 0x102871588 in Record::Record(std::__1::vector<DataType, std::__1::allocator<DataType>>&&) record.cc:8
    #3 0x1028b41e0 in HeapFilePage::vacuum(Schema const&) heap_file_page.cc:132
    #4 0x1028aa520 in HeapFile::vacuum() heap_file.cc:51
    #5 0x10280628c in main test_example_4.cc:50
    #6 0x18e7f3f24  (<unknown module>)

SUMMARY: AddressSanitizer: double-free (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x518ac) (BuildId: f0a7ac5c49bc3abc851181b6f92b308a32000000200000000100000000000b00) in wrap__ZdaPv+0x74
==93216==ABORTING
zsh: abort      ./build/Debug/tests/test_example_4 > output.out

Entiendo que probablemente este problema sea de referencia, al agregar un Record al array, el cual en otra parte se libera. Lo que no entiendo es como agregar a este array una copia del Record, o evitar que se libere.

cirojas commented 3 months ago

Record no es una clase pensada para generar una copia de si misma. Para que el compilador no te deje generar copias sin darte cuenta puedes añadir en la clase Record:

// src/relational_model/record.h
Record(std::vector<DataType>&& types);

Record(const Record& other) = delete; // new line

~Record();

Por lo tanto no vas a poder meter los records en un vector. Pero no es necesario para el vacuum que metas los records a un vector.