最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言?超詳細梳理總結動態(tài)內存管理

 更新時間:2022年03月30日 09:55:26   作者:二球懸鈴木丶  
動態(tài)內存是相對靜態(tài)內存而言的。所謂動態(tài)和靜態(tài)就是指內存的分配方式。動態(tài)內存是指在堆上分配的內存,而靜態(tài)內存是指在棧上分配的內存,本文帶你深入探究C語言中動態(tài)內存的管理

一.為什么存在動態(tài)內存分配

我們已經掌握的內存開辟方式有:

int a = 10;//在??臻g開辟4個字節(jié)的連續(xù)空間
int b[20] = { 0 };//在棧空間開辟20個字節(jié)的連續(xù)空間

這種開辟空間的方式有以下特點:

1.開辟空間的大小是固定的

2.開辟數(shù)組時必須指定大小

初學數(shù)組時,我寫過下面的錯誤代碼。

int N;
scanf("%d",&N);
int a[N]={ 0 };

可N是變量,不能用于數(shù)組元素個數(shù)的初始化。

如果我們需要的空間大小在程序運行時才能知道,那就只能試試動態(tài)內存開辟了。

二.動態(tài)內存函數(shù)的介紹

1.malloc和free

void* malloc (size_t size); 
void free (void* ptr);

malloc函數(shù)用于向內存申請一塊連續(xù)可用的空間,并且返回指向這塊空間的指針。

若開辟成功,返回指向這塊空間的指針

若開辟失敗,返回NULL指針,因此malloc的返回值一定要做檢查

使用完malloc函數(shù)要用free釋放申請的內存空間

#include<stdio.h>
#include<stdlib.h>
 
int main()
{
	int* p = (int*)malloc(40);//開辟40個字節(jié)的??臻g
	if (p == NULL)            //檢查是否為空指針
	{
		perror("malloc");
		return 1;
	}
	for (int i = 0; i < 10; i++)
	{
		*(p + i)=i;
	}
	free(p);                 //用完后釋放空間,注意參數(shù)為首地址
	p = NULL;                //置為空指針
}    

2.calloc

void* calloc (size_t num, size_t size)

calloc的兩個參數(shù)分別為申請元素的個數(shù)和每個元素的大小,

使用和malloc差不多,但是申請的空間會被初始化為0,

#include<stdio.h>
#include<stdlib.h>
 
int main()
{
	int* p = (int*)calloc(10, sizeof(int));
	if (p == NULL)
	{
		perror("calloc");
		return 1;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d  ", *(p + i)); //輸出為 10個0
	}
	free(p);
	p = NULL;
}

3.realloc

void* realloc (void* ptr, size_t size)

realloc用于重新設置要開辟內存空間的大小,可以是增大或減小

指針ptr是指向先前使用 malloc、calloc 或 realloc 分配的內存塊的指針。

size 是新開辟內存空間的大小

若原空間后面未開辟的空間足夠使用,則返回原先的起始地址

 若原空間后面未開辟的空間不足以填滿新開辟內存空間,

則會在某個地址開辟所需要的空間,free掉原空間的地址,

并且返回新的地址的起始地址

真 ·  一條龍服務

 若擴容失敗,會返回空指針,因此也要檢查是否是空指針

三.常見的動態(tài)內存錯誤

1.對NULL指針的解引用操作

void test()
{
    int *p = (int*)malloc(INT_MAX/4);
    *p = 20;
    free(p);
}

若p為空指針,則程序錯誤。

解決方案:檢查是否為空指針

2.對動態(tài)開辟空間的越界訪問

int main()
{
	int* p = (int*)calloc(10, sizeof(int));
	if (p == NULL)
	{
		perror("calloc");
		return 1;
	}
	for (int i = 0; i <= 10; i++)  //當i為10時,形成越界訪問,程序出錯
	{
		printf("%d  ", *(p + i));
	}
	free(p);
	p = NULL;
}

使用這塊空間時要注意是否已經越界訪問

3.對非動態(tài)開辟的空間使用free釋放

    int a = 10;
	int* p = &a;
	free(p);

一執(zhí)行,程序崩潰了

4.使用free釋放一塊動態(tài)開辟空間的一部分

void test()
{
	int* p = (int*)malloc(100);
	p++;
	free(p);
}

同樣會崩潰

5.對同一塊開辟的空間多次釋放

void test()
{
	int* p = (int*)malloc(100);
	free(p);
	free(p);
}

沒錯,又又又崩潰了,就不上圖了

6.動態(tài)內存開辟忘記釋放(內存泄漏)

如果使用空間后不釋放,會導致內存泄漏。

內存泄漏的堆積,這會最終消耗盡系統(tǒng)所有的內存。

四.幾個經典的筆試題

第一個

void GetMemory(char* p)            //對空指針解引用
{
	p = (char*)malloc(100);        //內存泄露
}
void test()
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world");    
	printf(str);
}
 
int main()
{
	test();
 
}

p是str的一份臨時拷貝,指向malloc申請的起始地址,

出了函數(shù)之后,內存還給系統(tǒng),str仍為空指針,strcpy把“hello world”放進空指針

第二個

char *GetMemory(void)
{
	char p[] = "hello world";
	return p;
}
void test()
{
	char* str = NULL;
	str=GetMemory();        //野指針str
	printf(str);
}
 
int main()
{
	test();
 
}

定義字符串p,并返回p的地址

但是當出了這個函數(shù),內存還給系統(tǒng),沒有使用權限

指針變?yōu)?/p>

第三個

void GetMemory(char** p,int num)            //傳址調用
{
	*p = (char*)malloc(num);        
}
void test()
{
	char* str = NULL;
	GetMemory(&str,100);
	strcpy(str, "hello world");
	printf(str);                                
                                            //沒有free
}
 
int main()
{
	test();
 
}

打印hello world

沒有釋放空間

第四個

void GetMemory(char** p,int num)
{
	*p = (char*)malloc(num);
}
void test()
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello world");
	free(str);                            //還給你,我還要用,哼~
	if (str != NULL)
	{
		strcpy(str, "!!!");
		printf(str);
	}
}
 
int main()
{
	test();
 
}

開辟100個字節(jié)的空間后,又把這塊空間還給操作系統(tǒng)。

再次把“!??!”放進這塊空間,非法修改

tips:動態(tài)內存管理是在堆區(qū)上進行的。

到此這篇關于C語言 超詳細梳理總結動態(tài)內存管理的文章就介紹到這了,更多相關C語言 動態(tài)內存管理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C/C++?Qt?Tree與Tab組件實現(xiàn)分頁菜單功能

    C/C++?Qt?Tree與Tab組件實現(xiàn)分頁菜單功能

    這篇文章主要介紹了C/C++?Qt?Tree與Tab組件實現(xiàn)分頁菜單功能,實現(xiàn)一個類似于樹形菜單欄的功能,當用戶點擊菜單欄中的選項時則會跳轉到不同的頁面上,本文簡單給大家分享實現(xiàn)代碼,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • 詳解C語言中free()函數(shù)與getpagesize()函數(shù)的使用

    詳解C語言中free()函數(shù)與getpagesize()函數(shù)的使用

    這篇文章主要介紹了詳解C語言中free()函數(shù)與getpagesize()函數(shù)的使用,是C語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-08-08
  • VC自定義消息響應函數(shù)postmessage用法示例

    VC自定義消息響應函數(shù)postmessage用法示例

    這篇文章主要介紹了VC自定義消息響應函數(shù)postmessage用法示例,并對比說明了postmessage與sendmessage的用法區(qū)別,需要的朋友可以參考下
    2014-10-10
  • 詳解Matlab如何繪制?;鶊D

    詳解Matlab如何繪制?;鶊D

    ?;鶊D是一種特定類型的流程圖,圖中延伸的分支的寬度對應數(shù)據(jù)流量的大小,通常應用于能源、材料成分、金融等數(shù)據(jù)的可視化分析。本文將用Matlab繪制好看的?;鶊D,需要的可以參考一下
    2022-03-03
  • 關于c語言指針的兩處小tip分享

    關于c語言指針的兩處小tip分享

    本篇文章是對c語言中指針的兩處小tip進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Qt實現(xiàn)簡單的TCP通信

    Qt實現(xiàn)簡單的TCP通信

    這篇文章主要為大家詳細介紹了Qt實現(xiàn)簡單的TCP通信,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Linux管道揭秘之匿名管道連接進程世界的方法

    Linux管道揭秘之匿名管道連接進程世界的方法

    文章介紹了Linux中的管道(Pipe)概念,包括其定義、作用、類型、工作原理以及如何在父子進程間使用,匿名管道是進程間通信的一種機制,通過pipe()系統(tǒng)調用創(chuàng)建,具有讀端和寫端文件描述符,文章詳細解釋了匿名管道的創(chuàng)建、使用流程、4種情況和5種特性
    2024-11-11
  • 詳解C++ sort函數(shù)的cmp參數(shù)

    詳解C++ sort函數(shù)的cmp參數(shù)

    這篇文章主要介紹了C++ sort函數(shù)的cmp參數(shù),以升降排序個結構體的排序展開的話題,感興趣的小伙伴可以參考下面文章內容
    2021-09-09
  • C語言程序設計50例(經典收藏)

    C語言程序設計50例(經典收藏)

    本篇文章是對C語言程序設計的50個小案例進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • 關于c++編譯protobuf時提示LNK2001 無法解析的外部符號的問題

    關于c++編譯protobuf時提示LNK2001 無法解析的外部符號的問題

    這篇文章主要介紹了關于c++編譯protobuf時提示LNK2001 無法解析的外部符號的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12

最新評論

孟村| 北川| 南阳市| 咸阳市| 清镇市| 章丘市| 平陆县| 安宁市| 抚松县| 元朗区| 水城县| 奉贤区| 林周县| 江源县| 鹿邑县| 霍城县| 开鲁县| 汉川市| 靖远县| 云浮市| 府谷县| 石家庄市| 惠东县| 黎城县| 宁远县| 陕西省| 丰县| 左贡县| 沧州市| 抚远县| 顺昌县| 桓台县| 舞钢市| 陆川县| 慈利县| 江油市| 万盛区| 靖西县| 江永县| 天峨县| 建瓯市|