C++ 内存基本构件new [] /delete []的意义、内存泄漏原因、VC下cookie的基本布局

目录

  • 一、对new [] delete [] 的理解
    • 1、delete的[]遗漏会带来什么影响
  • 二、以示例探讨
  • 三、cookie的理解

一、对new [] delete [] 的理解

new的对象是个array类型的。

Complex* pca = new Complex[3];
//唤起三次ctor
//无法借由参数给予初值
...
delete[] pca;	//唤起3次dtor

如下图,new出来的是一个array,大小为3.
new的时候要调用3次ctor,delete的时候需要调用3次dtor。分配一个array的时候,会顺带分配一个cookie,用来记录信息,最主要的就是array的长度了。
在这里插入图片描述

1、delete的[]遗漏会带来什么影响

如果delete后面不加[],编译器会以为只需要delete所指的对象,所以只会调用一次dtor,然而cookie记录中的array长度并没有改变,此时就会少还一些内存给操作系统,从而导致内存泄漏。
str1、str2、str3会被完整回收,但是在回收之前需要调用析构函数。由于string在构造上会带有一个指针,指针指向真正的字符串的内存空间。调用三次dtor,会被很干净地清掉。而少加了[],会就只调用一次dtor,导致三块只释放掉了一块
注意泄露的内存不是str1 2 3,而是指向的真正的字符串的内存空间。
在这里插入图片描述
**如果这里的array里面的元素类型是复数Complex,就不会造成内存泄漏,因为复数里面不包含指针。所以调用三次和调用一次也就无所谓了。**不过为了统一,还是要加上[]。

二、以示例探讨

示例代码:
A有一个默认构造函数,因为我们在new一个数组的时候不能一一地给定值,我们new是时候会调用三次构造函数。
构造函数和析构函数会在屏幕上输出占用内存位置

class A
{
public:int id;A() : id(0)      { cout << "default ctor. this="  << this << " id=" << id << endl;  }A(int i) : id(i) { cout << "ctor. this="  << this << " id=" << id << endl;  }~A()             { cout << "dtor. this="  << this << " id=" << id << endl;  }
};A* buf = new A[size];  //default ctor 3 次. [0]先於[1]先於[2])//A必須有 default ctor, 否則 [Error] no matching function for call to 'jj02::A::A()'A* tmp = buf;   cout << "buf=" << buf << "  tmp=" << tmp << endl;	for(int i = 0; i < size; ++i)new (tmp++) A(i);  		//3次 ctor cout << "buf=" << buf << "  tmp=" << tmp << endl;delete [] buf;    //dtor three times (次序逆反, [2]先於[1]先於[0])	

执行结果:
1、默认构造函数,默认id= 0 ;
2、this指针会自动移动,间距是一个对象的大小(int 4个字节)
3、移动指针,设初值,调用有参构造函数
4、需要注意这样的语法new(指针,指向已经分配的内存,我们在指针所指的地方进行设置初值) A(i),这属于placement new 的用法,之后的笔记会详细讲到。
5、循环过后id被修改,地址没有被修改
6、最后delete[],观察可知,调用了3次析构函数,析构的次序与构造的次序相反。(不同的编译环境析构次序可能不同)
在这里插入图片描述

三、cookie的理解

在做内存管理的时候,会有一个很大的诉求,就是不要这个cookie,所以cookie的存在以及大小是我们需要理解度的。
下面是VC6中,观察malloc给我们的内存布局:而我们获得的值指向分配的10个int数据的起始地址*pi.可以看到,除了我们认定的需要的10个int外,malloc还会分配32bytes和4bytes(橙色部分)。另外还有上cookie和下cookie,负责记录整块的大小
另外还有一个pad区域,这是由于在VC6下,malloc分配的内存必须是16bytes的倍数,如果不是,则需要填充额外内存使之为16bytes的倍数。
注意cookie记录的分配的内存大小为60h,不过最后一个bit要被用做on or off 的状态的切换,所以为61h。(存疑,不是很理解这句话,之后再补上理解。)上下cookie的数值一样。
这里的delete加不加[]是没有影响的。
在这里插入图片描述
如果这里我们不是存放的int类型的数据,而是放的是一个对象,并且它的析构函数是有意义的,此时编译器创造array的方式会有所不同。
注意每个demo对象中存放的是三个int,我们new了3个demo,分配的内存与之前相比多了一个3,即3个demo。
delete不加[],编译器将p当做普通指针,指向一块对象,然后以一块对象的方式去解释布局,但是此刻的布局与之前不同,多了一个3,所以解释会发生错误。
使用array new和array delete时,内存块分配是不一样的。array元素个数被写到内存块里去了。
60h内存计算方式:
60h = 32(debugger header) + 4(3:元素个数,int类型,4个bytes) + 3 x 12 (3个 demo object) + 4 (no man land) +12(pad) + 4 x 2(上喜下两个cookie)= 96个byte = 60h个byte(pad是会变动的)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377511.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenJudge计算概论-找出第k大的数

/* 找出第k大的数 总时间限制: 1000ms 内存限制: 1000kB 描述 用户输入N和K&#xff0c;然后接着输入N个正整数&#xff08;无序的&#xff09;&#xff0c;程序在不对N个整数排序的情况下&#xff0c;找出第K大的数。注意&#xff0c;第K大的数意味着从大到小排在第K位的数。并…

01背包怎么不重复_带有重复物品的背包

01背包怎么不重复Problem statement: 问题陈述&#xff1a; Weights and values are given for n items along with the maximum capacity allowed W. What is the maximum value we can achieve if we can pick any weights, any number of times for the total allowed capa…

jQuery数组处理汇总

有段时间没写什么了, 打算把jquery中的比较常用的数组处理方法汇总一下 $.each(array, [callback])遍历,很常用 ?12345678var arr [javascript, php, java, c, c#, perl, vb, html, css, objective-c];$.each(arr, function(key, val) {// firebug consoleconsole.log(index …

C++ 内存基本构件 placement new

用法以及编译器解释 placement new 允许我们将object构建于已经分配的内存上。(所以此时必须有个指针指向已经分配好的内存) 没有所谓的placement delete &#xff0c;因为placement new根本没有分配内存. 也有种说法&#xff0c;是将placement new对应的内存释放掉的操作为pl…

二维数组for遍历

<?php$conarray(array(1,高某,A公司,北京市,010,abc),array(2,罗某,B公司,天津市,020,bcd),array(3,冯某,C公司,上海市,021,cdf),array(4,书某,D公司,重庆市,022,dfg));echo <table border"1" width"600" align"center">;echo <cap…

Xcode调试相关小结

一.设置NSZombieEnabled 使用NSZombieEnabled功能,当代码中访问已经释放了内存的地方,会给你下面这样的提示,而不仅仅是EXEC_BAD_ACCESS: 2008-10-03 18:10:39.933 HelloWorld[1026:20b] *** -[GSFont ascender]: message sent to deallocated instance 0x126550 如果要查看上面…

ONGC的完整形式是什么?

ONGC&#xff1a;石油天然气公司 (ONGC: Oil and Natural Gas Corporation) ONGC is an abbreviation of Oil and Natural Gas Corporation. It is an Indian multinational corporation that is one of the leading producers of crude oil and natural gas in India. Its hea…

C/C++代码优化方法

目录优化概述_O0优化_O1优化_O2优化_O3优化volatile关键字避免优化优化概述 如果将未经优化的C语言程序直接运行会发现运行效率较低&#xff0c;并且产生的代码较大&#xff0c;而通过优化可以较好地解决这些问题。 优化的作用是对循环进行化简&#xff0c;重新组织表达式和声…

大学生应当趁早谋划未来(二)--给表弟的建议

背景表弟&#xff0c;大四&#xff0c;湖北某二本院校&#xff0c;计算机相关专业。大学期间&#xff0c;对Java等编程没有兴趣&#xff0c;几乎没怎么学习。平时&#xff0c;课程比较多&#xff0c;每天6节左右。课外&#xff0c;自己去挣点生活费,父亲生病了。困境最近在找工…

UVa 490 - Rotating Sentences

把输入的字符顺时针旋转90度。 1 #include<stdio.h>2 #include<string.h>3 4 int main()5 {6 int i, j, max, n, m;7 char s[105][105];8 max0;9 memset(s, \0, sizeof(s)); 10 for (i0; gets(s[i]); i) 11 { 12 nstrlen(s[i]); 1…

node 大写_大写Node.js模块

node 大写Today, lets see a third party module that helps us in working with upper-case letters without necessarily typing them in upper-case in our source code. 今天&#xff0c;让我们看一个第三方模块&#xff0c;它可以帮助我们处理大写字母&#xff0c;而不必在…

1704:baoge的洗漱难题[黄]

baoge的洗漱难题[黄] Time Limit: 5000 ms Memory Limit: 65536 KB Total Submit: 79 Accepted: 21 Description众所周知&#xff0c;地大19楼的盥洗室非常小&#xff0c;所以经常会非常拥挤&#xff0c;很多时候去洗漱的时候不得不排很长的队。有时候baoge会排上半小时…

HDU嵌入式实验课程大作业分析报告

目录作业要求设计原理与思路扩展任务说明课程感受友情链接工程链接作业要求 体能测试记录仪设计 基于课程发放的实验板&#xff0c;设计一个带有计时和数据采集功能的体能测试记录仪。 基本设计内容 功能1&#xff1a;对应1000米体测场景&#xff0c;使用充电宝供电&#x…

COJ 1030 素数槽

http://acm.csu.edu.cn/OnlineJudge/problem.php?id1030 用线性筛素数果然快多了。 #include<cstdio> #include<cstring> #include<cstdlib> #define MAXN 1300000 bool is_p[MAXN];void calc() {for( int i 1; i < MAXN; i )is_p[i] true;is_p[1] fa…

html注释引用公共头部_HTML注释和引用

html注释引用公共头部HTML注释 (HTML Comments) To insert a comment in an HTML document, the comment tags are used. The comments are used to provide some information that could be useful for anyone who views the code of the webpage. The comments can be insert…

java连接oracle数据库 -- jdbc连接

a. 倒入oracle的jar包 b. 编写java文件 package com.sp; import java.sql.*; //使用jdbc连接oracle public class MyOra2 {/*** param args*/public static void main(String[] args) {// TODO Auto-generated method stubtry {Class.forName("oracle.jdbc.dri…

HDB3码的编码

编码规则 1、源码是1时&#xff0c;暂时不变&#xff1b; 2、连0不超过3个时不变&#xff0c;有4个或以上连0时把每4个0换为取代节&#xff0c;即B00V&#xff1b; 3、确定B是0还是1&#xff1a;第一个B一般取0&#xff0c;若两个取代节之间1的个数为偶&#xff0c;易推得后者…

地图加载(安全沙箱问题及解决方案)

基于Flash开发的软件浏览器插件会受到应用沙盒限制&#xff0c;譬如说在本机发布了地图服务&#xff0c;在flex中使用localhost获取地图时一切正常&#xff0c;但改成IP地址后就会报安全沙箱错误。 Flash Player对访问外部资源有比较严格的限制&#xff0c;因此如果需要访问…

批量去除文件空格

import osfilepath r"G:\picture" # 文件目录名 allfilepath os.listdir(filepath)for file in allfilepath: # 改目录下的文件名oldpath filepath \\ filenewname file.replace( , ) # 在原先文件名中去除空格&#xff0c;也就是用null替代空格newpath fil…

python 初始化 元组_在Python中重新初始化元组

python 初始化 元组Python | 重新初始化元组 (Python | Reinitializing tuple) In this tutorial, we will learn how can we reinitialize a tuple with a new set of elements/objects? 在本教程中&#xff0c;我们将学习如何使用一组新的元素/对象重新初始化元组&#xff1…