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——多线程下解决生产消费者模型
我们学习了操作系统,想必对生产消费者问题都不陌生.作为同步互斥问题的一个经典案例,生产消费者模型其实是解决实际问题的基础模型,解决很多的实际问题都会依赖于它.而此模型要解决最大的问题便是同步与互斥.而 ...
随机推荐
- 【LeetCode-面试算法经典-Java实现】【096-Unique Binary Search Trees(唯一二叉搜索树)】
[096-Unique Binary Search Trees(唯一二叉搜索树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given n, how many s ...
- printk()函数的总结
我们在使用printk()函数中使用日志级别为的是使编程人员在编程过程中自定义地进行信息的输出,更加容易地掌握系统当前的状况.对程序的调试起到了很重要的作用.(下文中的日志级别和控制台日志控制级别是一 ...
- windows phone8.1:页面导航详解
小梦给大家带来windows phone 8.1应用开发实战教程,分享自己学习,开发过程中的经验和技巧. 今天给大家分享windows phone 8.1页面导航相关知识.涉及知识点如下: 页面一导航 ...
- ArcGIS Engine 编辑- IWorkspaceEdit
转自原文 ArcGIS Engine 编辑- IWorkspaceEdit 这个例子中,我创建了1000条要素,并结合缓冲将数据写到文件中,并且添加了时间统计,当然数据是我捏造的,还请原谅,这个花费的 ...
- C#基础readonly 与const
readonly 与 const readonly是运行时常量,const是编译期常量(在编译过程中已经把使用该值的都用值替代,不分配内存)readonly灵活性高,const效率高 readonly ...
- 使用RpcLite构建SOA/Web服务(Full .Net Framework)
使用RpcLite构建SOA/Web服务(Full .Net Framework) SOA框架系列 1. 使用RpcLite构建SOA/Web服务 2. 使用RpcLite构建SOA/Web服务(Fu ...
- hadoop 3.x 完全分布式集群搭建/异常处理/测试
共计三台虚拟机分别为hadoop002(master,存放namenode),hadoop003(workers,datanode以及resourcemanage),hadoop004(workers ...
- cordova插件整理
原文:cordova插件整理 1.获取当前应用的版本号 cordova plugin add cordova-plugin-app-version 2.获取网络连接信息 cordova plugin ...
- Ubuntu 16.04安装MinGW32(在/etc/apt/sources.list里添加源)
Ubuntu 16.04下直接使用命令安装MinGW32: sudo apt-get install mingw32 但是,会报错: Unable to locate package mingw3 ...
- 微信公众平台开发(1) 通用的工具类CommonUtil
1.通用的调用微信的方法 /** * * @param requestUrl 接口地址 * @param requestMethod 请求方法:POST.GET... * @param output ...