我正在使用mapPixel的概念创建一个地图网格(一个2D离散点数):一个类:
class MapPixel
{
friend class Map;
protected:
int x;
int y;
float height;
float vegetation;
std::vector<const MapPixel*> neib;
...methods declaration, default constructor/destructor
其中neib是指向其他MapPixel的指针列表,与之相邻。
我正在使用方法
void MapPixel::addNeib(const MapPixel* neib_)
{
neib.push_back(neib_);
}
添加一个指向neiber像素的指针来构建图形(因为边框的neib比中心像素少,这个列表与尺寸有关)。
我的程序是拥有一个带有成员的类Map
MapPixel **pixels;
在构造函数Map :: Map()中使用
pixels = new MapPixel*[width];
for (int i = 0; i < width; i++)
pixels[i] = new MapPixel[height];
我使用方法MapPixel :: addNode()来构建网络(例如)
pixels[i][j].addNeib(&pixels[i][j+1]);
并且在Map :: ~Map()中我按逆序删除MapPixel(不删除neibs以避免双重释放):
for (int i = 0; i < width; i++)
delete pixels[i];
delete pixels;
Valgrind说有几个大的内存泄漏如下:
2,509,088 bytes in 39,205 blocks are possibly lost in loss record 4,071 of 4,071
in MapPixel::addNeib(MapPixel const*) in Source/mappixel.cpp:52
1: malloc in vg_replace_malloc.c:266
2: operator new(unsigned long) in /usr/lib/libstdc++.6.0.9.dylib
3: __gnu_cxx::new_allocator<MapPixel const*>::allocate(unsigned long, void const*) in ...
4: std::_Vector_base<MapPixel const*, std::allocator<MapPixel const*> >::_M_allocate(unsigned long) in stl_vector.h:131
5: std::vector<MapPixel const*, std::allocator<MapPixel const*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<MapPixel const**, std::vector<MapPixel const*, std::allocator<MapPixel const*> > >, MapPixel const* const&) in vector.tcc:271
6: std::vector<MapPixel const*, std::allocator<MapPixel const*> >::push_back(MapPixel const* const&) in stl_vector.h:608
7: MapPixel::addNeib(MapPixel const*) in mappixel.cpp:52
所有与第52行相关:
neib.push_back(neib_);
有谁理解这个?现在我对是否可以使用std :: vector来构建像素的neib失去了信心。
答案 0 :(得分:1)
请注意,valgrind说“可能丢失”,而不是“肯定丢失”。差异很重要。请参阅here了解确切含义。
该错误是关于vector<>
实现代码分配的块,最有可能在vector
增长时调整包含元素的内存块的大小。如果你要分配MapPixel
的实例并忘记释放它们,你可能会得到这些,因为包含vector
然后无法释放它的内存,但是你也会得到关于你自己的代码的错误
除非!当您释放pixels
数组时,您使用的是delete[]
还是delete
?
更新:您正在使用delete
。您需要使用delete[]
。这确实是内存泄漏。使用new[]
分配的任何内容都必须使用delete[]
释放,否则只会为第一个元素调用正确的析构函数(即使是由编译器自动生成的析构函数)。
答案 1 :(得分:0)
正如已经提到的另一个答案,内存泄漏很可能是由错误的delete
运算符引起的。在构造函数中,使用operator new[]创建一个数组数组:
pixels = new MapPixel*[width];
for (int i = 0; i < width; i++)
pixels[i] = new MapPixel[height];
您需要使用相应的array-delete operator delete[]:
释放阵列的内存for (int i = 0; i < width; i++)
delete [] pixels[i];
delete [] pixels;
但是,我建议您使用嵌套std::vector
代替像素矩阵。这样您就可以免费获得内存管理。
std::vector<std::vector<MapPixel> > pixels;
// in constructor something like:
pixels.resize(width, std::vector<MapPixel>(height));
// nothing to do in destructor
对于你的邻居,我不会使用std :: vector,而是使用普通的MapPixel *neib[8];
(假设是摩尔社区)或者更确切地说是std::array<MapPixel*, 8> neib;
。但是我不知道你对这个项目有什么其他要求。
除了内存管理之外,使用STL容器还可以为您带来其他好处,例如方便的成员函数,它们不会衰减到指针,仅举几例。