二維指針動(dòng)態(tài)分配內(nèi)存連續(xù)問(wèn)題深入分析
#include <cstdlib>
#include <iostream>
using namespace std;
#define nWidth 3
#define nHeight 4
//內(nèi)存是否連續(xù)分配問(wèn)題
int main(int argc, char *argv[])
{
int **p = NULL;
p = (int**)malloc(nWidth*sizeof(int*));
if(p == NULL)
return -1;
cout<<"內(nèi)存的不連續(xù)分配:"<<endl;
for(int j = 0; j< nWidth; j++)
{
p[j] = (int*)malloc(nHeight*sizeof(int));
if(p[j] == NULL)
return -1;
}
for(int i = 0; i < nWidth; i++)
for(int j = 0; j < nHeight; j++)
{
printf("%p ",&p[i][j]);
if(j == nHeight-1)
cout<<endl;
}
cout<<endl;
for(int j = 0; j < nWidth; j++)
{
free(p[j]);
p[j] = NULL;
}
free(p);
p = NULL;
int **q = NULL;
q = (int**)malloc(nWidth*sizeof(int*));
if(q == NULL)
return -1;
cout<<"內(nèi)存的連續(xù)分配:"<<endl;
q[0] = (int*)malloc(nWidth*nHeight*sizeof(int));
if(q[0] == NULL)
{
free(q);
return -1;
}
for(int i = 1;i < nWidth; i++)
q[i] = q[i-1] + nHeight;
for(int i = 0; i < nWidth; i++)
for(int j = 0; j < nHeight; j++)
{
printf("%p ",&q[i][j]);
if(j == nHeight-1)
cout<<endl;
}
cout<<endl;
free(q[0]);
q[0] = NULL;
free(q);
q = NULL;
system("PAUSE");
return EXIT_SUCCESS;
}
運(yùn)行截圖如下:

如圖所示,兩種分配內(nèi)存的方法都能正確的分配內(nèi)存,但是內(nèi)存分配的空間確實(shí)不一樣的。
分析:
第一種分配方法:
首先,是對(duì)每一行分配,也就是 nWidth 中的每一個(gè)進(jìn)行分配,所以,我們可以看到每一行的內(nèi)存都是連續(xù)的,每一個(gè)都占據(jù)四個(gè)字節(jié)
但是,為nHeight分配內(nèi)存的時(shí)候,是隨機(jī)的進(jìn)行分配內(nèi)存,所以內(nèi)存的位置是不確定的,所以,出現(xiàn)了第一種情況
第二種分配方法:
首先,同樣是為 p 分配內(nèi)存,現(xiàn)在 p 指向一個(gè)位置
但是,在第二句中,我們需要注意,是直接在 p[0] 出分配了所有需要的內(nèi)存,所以,這個(gè)時(shí)候就全部分配完了,而且由于是一次性分配內(nèi)存,故內(nèi)存的地址肯定是連續(xù)的,運(yùn)行結(jié)果也證明了這一點(diǎn)
釋放內(nèi)存的兩種情況:
第一種情況由于是兩次不同的分配內(nèi)存,所以,在釋放內(nèi)存的時(shí)候,我們應(yīng)選擇不同的區(qū)域進(jìn)行釋放。
第二種情況,只是連續(xù)調(diào)用兩次 malloc ,所以,只需要連續(xù)兩次調(diào)用 free 即可完成釋放。
相關(guān)文章
C語(yǔ)言中單鏈表的基本操作(創(chuàng)建、銷毀、增刪查改等)
這篇文章主要介紹了C語(yǔ)言中單鏈表的基本操作(創(chuàng)建、銷毀、增刪查改等),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02C++使用easyx畫(huà)實(shí)時(shí)走動(dòng)的鐘表
這篇文章主要為大家詳細(xì)介紹了C++使用easyx畫(huà)實(shí)時(shí)走動(dòng)的鐘表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05C++和python實(shí)現(xiàn)單鏈表及其原理
這篇文章主要介紹了C++和python實(shí)現(xiàn)單鏈表及其原理,單鏈表是鏈表家族中的一員,每個(gè)節(jié)點(diǎn)依舊由數(shù)據(jù)域(data)和指針域(next)組成,鏈表的具體概念下面文章將詳細(xì)介紹,需要的小伙伴可以參考一下2022-03-03C++中成員函數(shù)和友元函數(shù)的使用及區(qū)別詳解
大家好,本篇文章主要講的是C++中成員函數(shù)和友元函數(shù)的使用及區(qū)別詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01C++類的返回值是*this的成員函數(shù)問(wèn)題
這篇文章主要介紹了C++類的返回值是*this的成員函數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C語(yǔ)言實(shí)現(xiàn)的循環(huán)單鏈表功能示例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)的循環(huán)單鏈表功能,結(jié)合實(shí)例形式分析了基于C語(yǔ)言實(shí)現(xiàn)的循環(huán)單鏈表定義、創(chuàng)建、添加、刪除、打印、排序等相關(guān)操作技巧,需要的朋友可以參考下2018-04-04C++中的按位與&、按位與或|、按位異或^運(yùn)算符詳解
這篇文章主要介紹了C++中的按位與&、按位與或|、按位異或^運(yùn)算符,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01