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.pswp.cn/news/377511.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377511.shtml
英文地址,請注明出處:http://en.pswp.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…