Valgrind 内存泄漏与动态数组 C++
Posted
技术标签:
【中文标题】Valgrind 内存泄漏与动态数组 C++【英文标题】:Valgrind memory leak with dynamic arrays C++ 【发布时间】:2018-01-14 23:42:52 【问题描述】:我尝试了几种方法来解决这个问题,但似乎无法弄清楚。 Valgrind 用我的 resize 方法指出了内存泄漏,我觉得我可能遗漏了一些简单的东西。
.h 文件
private:
int* pArray; // stores math expression
int currentSize; // size of array
.cpp
void Prog::resize(int newSize)
cout << "Address of polynomial:\t\t\t" << &pArray << endl;
int* temp = new int[newSize] 0;
cout << "Address of temp:\t\t\t" << &temp << endl;
copy(temp, pArray);
delete[] pArray;
pArray = temp;
cout << "Address of pArray after swap:\t" << &pArray << endl;
temp = nullptr;
currentSize = newSize;
void Prog::copy(int* to, int* from)
for (int i = 0; i < currentSize; i++)
to[i] = from[i];
我添加了 cout 以查看地址发生了什么,因为我认为在将 pArray 交换为 temp 后它会打印出 temp 位置的地址,但它似乎保留了其原始位置。这是应该发生的事情吗?
我已经尝试创建一个交换方法,但我使用它时问题仍然存在。
void Prog::swap(int*& to, int*& from)
int* temp = to;
to = from;
from = temp;
这是我从 Valgrind 运行程序时的输出。
程序片段
Address of pArray: 0000006741EFF218
Address of temp: 0000006741EFEEE8
Address of pArray after swap: 0000006741EFF218
D = +50x^20000 +15x^11 +5x^10 -12x^7 -4x^6 +30x^5 +4x^4 -2x^3 +50
Valgrind
==22696== 24 bytes in 1 blocks are definitely lost in loss record 1 of 12
==22696== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22696== by 0x40230A: Prog::resize(int) (Prog.cpp:332)
==22696== by 0x401DD7: Prog::operator=(Prog const&) (Prog.cpp:171)
==22696== by 0x400DEE: main (lab1.cpp:36)
==22696==
==22696== 36 bytes in 1 blocks are definitely lost in loss record 2 of 12
==22696== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22696== by 0x40230A: Prog::resize(int) (Prog.cpp:332)
==22696== by 0x401DD7: Prog::operator=(Prog const&) (Prog.cpp:171)
==22696== by 0x400DD5: main (lab1.cpp:35)
==22696==
==22696== 52 bytes in 1 blocks are definitely lost in loss record 9 of 12
==22696== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22696== by 0x40230A: Prog::resize(int) (Prog.cpp:332)
==22696== by 0x401DD7: Prog::operator=(Prog const&) (Prog.cpp:171)
==22696== by 0x40201D: Prog::operator*=(Prog const&) (Prog.cpp:214)
==22696== by 0x40116D: main (lab1.cpp:55)
感谢任何帮助!
编辑 - 赋值运算符也显示了内存泄漏,但它使用了 resize 方法,这就是我忽略它的原因,但这里请求的其余代码:
Prog::Prog() : currentSize(1)
pArray = new int[currentSize] 0;
Prog::~Prog()
for (int i = 0; i < currentSize; i++)
this->pArray[i] = 0;
currentSize = 0;
delete[] pArray;
pArray = nullptr;
Prog& Prog::operator=(const Prog& rhs)
if (this == &rhs)
return *this;
for (int i = 0; i < currentSize; i++)
pArray[i] = 0;
if (this->currentSize < rhs.currentSize)
resize(rhs.currentSize + 1);
currentSize = rhs.currentSize;
pArray = new int[currentSize];
for (int i = 0; i < currentSize; i++)
pArray[i] = rhs.pArray[i];
else
for (int j = 0; j < rhs.currentSize; j++)
pArray[j] = rhs.pArray[j];
return *this;
【问题讨论】:
请发布您的构造函数、赋值运算符和析构函数,因为问题可能在于operator=
如何处理返回的数据。 (哦,调查std::shared_ptr
和朋友,因为他们会简化事情)
泄漏在 Prog::operator=(Prog const&) (Prog.cpp:171) 中,您避免发布。
@KenY-N 我添加了其余部分。我目前不允许使用智能指针(虽然我没有看到提到 shared_pointer)。我不能使用 STL 库中的任何东西(带有其大小的向量或数组等)
@endanegered -- 你真的应该编写一个复制构造函数Prog::Prog(const Prog&)
。然后你的赋值运算符将变成一个使用swap
的三行函数。
除其他问题外,如果newSize < currentSize
则copy()
在Prog::Resize()
中的调用具有未定义的行为。
【参考方案1】:
在您的operator=
中,您调用resize
,然后在接下来的两个语句中基本上再次执行相同的操作。由于resize
分配内存(并将该指针存储到pArray
,然后你用一个新值覆盖operator=
中的那个值而不释放以前的值,你就会得到泄漏。
【讨论】:
哇...我只是看错了地方,并假设它正在调整大小,因为它在每个块中丢失。谢谢!我正在失去理智,它正盯着我的脸。以上是关于Valgrind 内存泄漏与动态数组 C++的主要内容,如果未能解决你的问题,请参考以下文章