- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在编写一个可调整大小的数组类 (std::vector),作为练习,使用手动指针(因为我想在开始使用智能指针之前知道它们是如何工作的)。但是,Valgrind 报告 checkMax() 函数存在内存泄漏。
template <typename T>
class Array{
public:
Array() : len(0),maxLen(1){
array=new T[maxLen];
// ........
}
Array(unsigned length, T&content=0) : len(length),maxLen(length*2){
array=new T[maxLen];
//..............
}
~Array(){
//delete[] array;
}
//..............
void push_back(const T& content){
checkMax();
// do stuff...
}
private:
T* array;
unsigned int len;
unsigned int maxLen;
..
void checkMax(){
if(len==maxLen){
//allocate more memory for the array
maxLen*=2;
T*temp=new T[maxLen]; // ------------- MEMORY LEAK HERE -------------
for(unsigned int i=0; i<len; i++){
temp[i]=array[i];
}
delete [] array;
array=temp;
}
}
};
我在这里只发布了与内存相关的代码。
我不明白为什么 Valgrind 在指定行报告内存泄漏。在将旧数组内容复制到扩大后的数组后,我确实删除了旧数组,两行之后。
此外,如果我在析构函数中取消注释 delete[] 函数,我会得到一个异常 double free or corruption
并且 Valgrind 报告一个无效删除(暗示重新删除),所以我完全糊涂了。有什么想法吗?
编辑: 感谢您的早期回复!阅读评论后,我发现问题不在于我的类,而在于我调用的另一个函数以 Array 类作为参数。如果我删除对该函数的调用,并在类中添加删除调用,则不会发生内存泄漏。这是我的功能:
template <typename T>
void printContents(Array<T> ar){
for(unsigned int i=0; i<ar.size(); i++){
cout<<"Content at i in array = " << ar.at(i) << endl;
}
}
在阅读三规则(感谢 chris)和 Grizzly 发布的答案后,我现在明白了为什么 delete[] 无效。因为我没有重载复制构造函数,所以发生了浅复制,因此,我的数组指针被分配到ar中的指针,当ar超出范围时,调用了delete[],从而使我在主函数中的删除 无效 。因此,我得到了异常(exception)。如果我删除删除,那么数组显然会保持分配状态并导致内存泄漏。
感谢您的帮助,我认为 Grizzly 的回答是正确的。
最佳答案
您没有在析构函数中调用 delete[]
就会泄漏内存。这意味着当您最后一次在对象上调用 checkMax
时分配的数组(对象中的“最终”数组)永远不会被调用。所以要解决这个问题,你应该在析构函数中取消注释 delete[]
正如您所提到的,这会给您带来双重免费的问题。这是基于违反三的规则(在 C++03 中它是三的规则,在 C++11 中情况不那么明确,但对于这种情况,三的规则足以解决你的问题)。三原则基本上表明,当您定义自定义析构函数、复制构造函数或赋值运算符时,您需要定义所有这些。在这种情况下,您可能正在某处复制 Array
。这意味着两个实例将包含相同的指针并尝试在析构函数中将其删除。对同一个指针调用 delete 两次是错误的。要解决该问题,您需要定义自定义复制构造函数和赋值操作,在其中执行数组的深度复制(分配新内存并将内容复制过来)。
除此之外,我个人建议从智能指针开始,只有在您更好地掌握 C++ 之后,才开始尝试手动内存管理。
关于c++ - 内存泄漏;删除异常时引发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16749860/
我正在使用 SharePoint Online 并使用 Windows Azure 托管访问 SPO 的进程。 我们已将启动任务添加到 Azure 角色以安装 http://www.microsoft
我有一个函数,它获取包含时间的源文件(csv 文件),读取它,然后按顺序对行进行排序并将它们写入目标文件中。但是,如果源 csv 文件不存在,我需要引发 FileNotFoundError。我之前曾引
我试图在目录不存在时引发错误,然后再打开该目录中的文件。根据this response我应该为我的问题使用最具体的异常构造函数,我认为它是 NotADirectoryError。但是运行下面的代码我得
在编码/开发生命的一天或另一天,我们确实遇到了这个特殊的情况,这是最常见的异常(exception)之一。我的问题是关于的而不是。为什么(我知道当我们尝试访问实际上指向null的引用变量的属性时会引发
我想知道在 python 中是否可以在一个 except block 中引发异常并在稍后的 except block 中捕获它。我相信其他一些语言默认会这样做。 这是它的样子" try: som
我有以下代码: br = mechanize.Browser() br._factory.is_html = True br.form = mechanize._form.ParseString(''
我刚刚发现,如果您有一个引发 TOO_MANY_ROWS 异常的 SELECT INTO,该变量仍会从查询检索到的第一条记录中分配值。这是预期的行为吗? 这是我的例子: for co in my_cu
当 SSH 显示 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 我知道当您重新安装远程服务器时会发生这种情况,但我尝试列出 其他原因 . 我知道如何
我有一个枚举和一个 EnumMap . 我将 map 放入一个类中以隐藏“字节”值。所以我有一个set(Parameter, int)和set(Parameter, boolean)方法。 publi
在什么情况下会redis-py引发以下 AttributeError 异常? redis-py 不是设计来引发仅基于 redis.exceptions.RedisError 的异常吗? 什么是合理的处
可悲的是,对此异常的引用通常具有异国情调,并且可能发生在您例如通过 Assembly.GetTypes() 枚举类型- 举个例子,它发生在我们的一个部署上,但同一组程序集在集成服务器上运行良好。 为了
我正在为 Android 下的特定平板电脑克隆一个存储库并获取源代码,我必须执行一个 python 脚本。当我执行它时,我收到此错误消息: Traceback (most recent call la
首先,执行此操作(在运行 4.4.2 的 Nexus 5 上测试): 将 PRIORITY_LOW 通知传递给 Service.startForeground()。 观察通知不显示在状态栏中。 使用相
我尝试使用 AppEngine 的 python 模块 api 来获取使用基本缩放的模块的实例数。在我模块的 yaml 文件中,我明确设置了 max_instances 参数。我希望 get_num_
当我如下运行我的 spark python 代码时: import pyspark conf = (pyspark.SparkConf() .setMaster("local")
在我的系统上,一段适用于 Python 2 的代码不适用于 Python 3。 f = open("plotwidget.svg") svgData = f.read() xml_stream = Q
我是 PHP 和 SQL 的新手,但我正在创建一个登录系统。我遇到的问题是: You have an error in your SQL syntax; check the manual that c
我有一个使用 ebaysdk 库的 python 代码,当我运行代码并输入关键字进行搜索时,我得到了这个错误。 Traceback (most recent call last): File "eba
当我将表单数据发送到我的 Flask 应用程序时,出现以下错误。它说它将使用 UTF-8 编码,但语言环境已经是 UTF-8。这个错误是什么意思? /home/.virtualenvs/project
在python2.7中,跟随pympler example : from anotherfile import somefunction, somecustomclass from os import
我是一名优秀的程序员,十分优秀!