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——多线程下解决生产消费者模型
我们学习了操作系统,想必对生产消费者问题都不陌生.作为同步互斥问题的一个经典案例,生产消费者模型其实是解决实际问题的基础模型,解决很多的实际问题都会依赖于它.而此模型要解决最大的问题便是同步与互斥.而 ...
随机推荐
- HTML/CSS 选择符优先级
CSS的选择符优先级 1.同级样式默认后者覆盖前者 2.样式优先级 类型(1) < class[type](10)=伪类(10) < id(100) < style行间样式(1000 ...
- Swift之动画总结
UIView动画个人笔记,代码简单,不过多赘述.1.定义三个View @IBOutlet weak var mFirstView: UIView! @IBOutlet weak var mSecond ...
- spring里头各种获取ApplicationContext的方法
为啥写这个文章呢?spring各个版本不同,以及和系统框架套在一起不同,导致获取的方式不同,网络上各种版本,太乱了,写获取方式的人都不写这个获取方式是在本地还是在WEB,在那种应用服务器下,在spri ...
- 通过onTouch来确定点击的是listView哪一个item
事实上这主要是用了ListView的一个方法,通过坐标就能够确定当前是哪一个listView,别的我就不多说了直接看看代码吧, lv_flide.setOnTouchListener(new OnTo ...
- 使用URLConnection获取网页信息的基本流程 分类: H1_ANDROID 2013-10-12 23:51 3646人阅读 评论(0) 收藏
参考自core java v2, chapter3 Networking. 注:URLConnection的子类HttpURLConnection被广泛用于Android网络客户端编程,它与apach ...
- 【codeforces 742A】Arpa’s hard exam and Mehrdad’s naive cheat
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- Django + Apache + wsgi配置和环境搭建(ubuntu)
上一篇写了Django + nginx + uwsgi配置和环境搭建(ubuntu) 由于公司服务器环境问题,又配置了apache的环境.记录例如以下: 一. 安装环境: #apache sudo a ...
- Opencv Surf算子中keyPoints,描述子Mat矩阵,配对向量DMatch里都包含了哪些好玩的东东?
Surf算法是一把牛刀,我们可以很轻易的从网上或各种Opencv教程里找到Surf的用例,把例程中的代码或贴或敲过来,满心期待的按下F5,当屏幕终于被满屏花花绿绿的小圆点或者N多道连接线条霸占时,内心 ...
- 一个封装比较完整的FTP类——clsFTP
前几天,看见园子里面的博友写了一个支持断点续传的FTP类,一时技痒,干脆写了个更完整的clsFtp类.只是我写这个clsFtp不是支持断点续传的目的,而是为了封装FTP几个基本常用的操作接口. 功能 ...
- 【t008】钱币变换问题
Time Limit: 2 second Memory Limit: 32 MB [问题描述] 给定 2*n 个方格,将其排成一行.选择两个相邻的方格,设置为空方格,初始时不放钱币.而其余的方格共放入 ...