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文 ...
- 【t063】最聪明的机器人
Time Limit: 1 second Memory Limit: 128 MB [问题描述] [背景] Wind设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了~ [问题描述] ...
- (八)RabbitMQ消息队列-通过Topic主题模式分发消息
原文:(八)RabbitMQ消息队列-通过Topic主题模式分发消息 前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对direct模式下通过 ...
- python高级学习目录
1. Linux介绍.命令1.1. 操作系统(科普章节) 1.2. 操作系统的发展史(科普章节) 1.3. 文件和目录 1.4. Ubuntu 图形界面入门 1.5. Linux 命令的基本使用 1. ...
- 一起talk C栗子吧(第八十三回:C语言实例--进程间通信概述)
各位看官们,大家好,前二回中咱们说的是进程停止的样例,这一回咱们说的样例是:进程间通信.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们.每一个进程都拥有自己的资源,假设不同进程之间须要共享 ...
- 用SQL找出前N名
业务系统中常常会有排名的需求,考试和比赛中则更普遍了.Excel 中也有个 Rank 函数供排名之用,数据库中更不例外了. 如果须要找出工资最高的前三个员工工资(及其员工号). 只是."前三 ...
- Android 带文字的图片分享
这里也记录下上下文,因为做了一个失物招领的App,当有人上交了失物之后,可以将这个消息分享出去,这个消息内容有物品的信息和图片,而微信SDK始终无法做到,就想着把物品信息嵌入到图片中分享出去,先放一个 ...
- php利用反射机制查找类和方法的所在位置
//参数1是类名,参数2是方法名 $func = new ReflectionMethod('UnifiedOrder_pub', 'getPrepayId'); //从第几行开始 $start = ...
- LeetCode -- 删除链表中值为k的元素
本题目比較直接,一次遍历遇到匹配的元素直接删除(通过n.next = n.next.next)就能够了,仅仅是须要考虑到:1.首节点的情况2.末节点的情况 下面为实现: public ListNode ...
- js实现表格配对小游戏
js实现表格配对小游戏 一.总结 一句话总结: 二.js实现表格配对 1.配对游戏案例说明 实例描述: 当用户点击两个相同的图案或字符后配对成功,全部配对成功后游戏获胜 案例008采用了大家常见的小游 ...