VC6下深入理解new[]和delete[](在多线程下new和delete的时候,必须选择上多线程库,不然可能造成进程崩溃)
代码
#include <iostream>
using namespace std; int g_i = 0; class TestClass
{
public:
int id; TestClass()
{
id = ++g_i;
cout << id << " TestClass created." << endl;
} ~TestClass()
{
cout << id << " TestClass deleted." << endl;
}
}; int main(int argc, char* argv[])
{
TestClass * pTestClass = new TestClass;
delete pTestClass; return 0;
}
编译运行之后可以看到:
1 TestClass created.
1 TestClass deleted.
反汇编之后可以看出,程序首先申请了4字节的空间,然后调用构造方法进行初始化,接着便把地址赋给了pTestClass,最后调用析构方法收尾并把空间释放掉:
代码
push 4
call operator_new ...... mov ecx, [ebp+var_18]
call TestClass__TestClass
mov [ebp+var_24], eax ...... push 1
mov ecx, [ebp+var_1C]
call TestClass___scalar_deleting_destructor
再来看看申请对象数组的情况,将main函数中的代码修改为:
TestClass * pTestClass = new TestClass[4];
delete [] pTestClass;
编译运行之后可以看到:
1 TestClass created.
2 TestClass created.
3 TestClass created.
4 TestClass created.
4 TestClass deleted.
3 TestClass deleted.
2 TestClass deleted.
1 TestClass deleted.
反汇编之后可以看出,程序首先申请了20字节空间,然后将数组大小存放到前4个字节,调用构造方法将后面的4个对象指针初始化(4*4+4=20B),接下来才把空间指针赋给pTestClass。在清除空间的时候,程序根据存储在前4个字节中的长度,通过一个循环来从后往前调用每个对象的析构方法,最后才把空间释放掉:
代码
push 14h
call operator_new ...... push offset TestClass___TestClass
push offset loc_40128F
mov eax, [ebp+var_18]
mov dword ptr [eax], 4
push 4
push 4
mov ecx, [ebp+var_18]
add ecx, 4
push ecx
call vector constructor iterator ...... push 3
mov ecx, [ebp+var_1C]
call TestClass___vector_deleting_destructor
那么如果将main函数中的代码修改为申请一个对象的数组,情况又如何呢?
TestClass * pTestClass = new TestClass[1];
delete [] pTestClass;
通过反汇编可以看出,即使是申请一个对象的指针数组,编译器的处理都是一样的,多申请4个字节的空间来保存数组大小。所以,只要在new操作时,使用了[],在delete时也必须使用[],否则,程序将把前面存贮数组大小的4个字节按照对象指针来处理,这样在调用析构方法的时候就会出错。
那么如果是在一个文件中进行new操作,在另一个文件中delete的时候,如何判断使用delete还是delete []呢?一种方法是用一个变量来保存新申请对象的个数,在delete的时候进行判断,如果个数大于1,使用delete[],否则使用delete;另一种方法是,在申请对象的时候,一律用上[],这样在delete的时候也一律用上[]就没问题。
最后我们来看看申请简单类型数组的情况,将main函数中代码改为:
int * pInt = new int[4];
delete [] pInt;
反汇编后可以看到,由于是简单数据类型,不需要调用构造方法和析构方法,在申请空间时,没有多申请4个字节的空间来保存数组大小,所以,调用delete进行删除和调用delete []进行删除是完全一样的。
push 10h
call operator_new ...... push edx
call free_4062B0
今天才发现,在多线程下new和delete的时候,必须选择上多线程库,不然可能造成进程崩溃,具体设置位置在工程设置“C/C++”选项卡的“Code Generation”下的“Use run-time library”中。
http://www.cnblogs.com/God4/articles/1887184.html#2320993
VC6下深入理解new[]和delete[](在多线程下new和delete的时候,必须选择上多线程库,不然可能造成进程崩溃)的更多相关文章
- ASP.NET MVC Filters 4种默认过滤器的使用【附示例】 数据库常见死锁原因及处理 .NET源码中的链表 多线程下C#如何保证线程安全? .net实现支付宝在线支付 彻头彻尾理解单例模式与多线程 App.Config详解及读写操作 判断客户端是iOS还是Android,判断是不是在微信浏览器打开
ASP.NET MVC Filters 4种默认过滤器的使用[附示例] 过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响 ...
- [转帖]/proc/sys/net/ipv4/ 下参数理解
/proc/sys/net/ipv4/ 下参数理解,方便服务器优化 2017年06月02日 16:52:27 庞叶蒙 阅读数 3065 https://blog.csdn.net/pangyemeng ...
- 对于多线程下Servlet以及Session的一些理解
今天,小伙伴突然问到了Servlet是不是线程安全的问题.脑子当时一卡壳,只想到了单实例多线程.这里做一些总结. Servlet体系是建立在Java多线程的基础之上的,它的生命周期是由Tomcat来维 ...
- 定制自己的new和delete:operator new 和 operator delete
new和delete不同用法 基本用法 int * aptr = new int(10); delete aptr, aptr = nullptr; 上面的代码是我们最基本也是最常见的使用new和de ...
- Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask
CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到 ...
- Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger
前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲 ...
- Effective C++ 第二版 5)new和delete形式 6) 析构函数里的delete
内存管理 1)正确得到: 正确调用内存分配和释放程序; 2)有效使用: 写特定版本的内存分配和释放程序; C中用mallco分配的内存没有用free返回, 就会产生内存泄漏, C++中则是new和de ...
- 【JAVA】HashMap的原理及多线程下死循环的原因
再次翻到以前工作中遇到的一个问题,HashMap在多线程下会出现死循环的问题,以前只是知道会死循环,导致CPU100%把机器拖跨,今天来彻底看看 首先来看下,HashMap的原理:HashMap是一个 ...
- Linux——多线程下解决生产消费者模型
我们学习了操作系统,想必对生产消费者问题都不陌生.作为同步互斥问题的一个经典案例,生产消费者模型其实是解决实际问题的基础模型,解决很多的实际问题都会依赖于它.而此模型要解决最大的问题便是同步与互斥.而 ...
随机推荐
- 35、在编译Linux内核中增加程序需要完成以下3项工作
在编译Linux内核中增加程序需要完成以下3项工作: 将编写的源代码拷入Linux内核源代码的相应目录. 在目录的Kconfig文件中增加关于新源代码对应项目的编译配置选项 在目录的Makefile文 ...
- linux系统 wm9713声卡配置 记录
近期在搞wm9713的外音播放和耳机的检測,搞了几天不负所望,最终搞定了.现记录例如以下,开发板为real210 v6.2版本号: 假设要让外音输出,那么确保wm9713的0x1c寄存器的值为0x12 ...
- javascrit开发的基本代码结构的
今天看到群里一个demo,简单看了一下. 然后自己就写了一个通用的javascrit开发的基本代码结构的js文件. 代码例如以下: (function($,win){ //定义全局变量对象 var o ...
- js获取图片的尺寸
$("<img/>").attr("src", "http://www.example.com/images/bag001.jpg&quo ...
- Struts(22)标签库具体解释
要使用Struts2的标签,仅仅须要在JSP页面加入例如以下一行定义就可以: <%@ taglib prefix="s" uri="/struts-tags&quo ...
- 【b802】火柴棒等式
Time Limit: 1 second Memory Limit: 50 MB [问题描述] 给你n根火柴棍,你可以拼出多少个形如"A+B=C"的等式?等式中的A.B.C是用火柴 ...
- 【STL】各容器成员对比表
http://www.cnblogs.com/fangyukuan/archive/2010/09/21/1832675.html Sequence containers Associative co ...
- [Ramda] Pick and Omit Properties from Objects Using Ramda
Sometimes you just need a subset of an object. In this lesson, we'll cover how you can accomplish th ...
- Git远程操作具体解释
Git是眼下最流行的版本号管理系统,学会Git差点儿成了开发人员的必备技能. Git有非常多优势,当中之中的一个就是远程操作非常简便.本文具体介绍5个Git命令,它们的概念和使用方法,理解了这些内容. ...
- WPF Opacity 最小值多少会被击穿
粗略测试 这样也行.再小不懂咯(跟Double精度有关???) <WrapPanel.Background> <SolidColorBrush x:Name="opacit ...