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

C語(yǔ)言 動(dòng)態(tài)內(nèi)存開(kāi)辟常見(jiàn)問(wèn)題解決與分析流程

 更新時(shí)間:2022年03月16日 10:26:00   作者:K穩(wěn)重  
動(dòng)態(tài)內(nèi)存是相對(duì)靜態(tài)內(nèi)存而言的。所謂動(dòng)態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存

前言

當(dāng)我們用動(dòng)態(tài)內(nèi)存分配函數(shù)來(lái)編寫(xiě)程序時(shí),在編寫(xiě)的過(guò)程中常常會(huì)產(chǎn)生一些不易被察覺(jué),被發(fā)現(xiàn)的錯(cuò)誤,例如對(duì)NULL指針的解引用操作,對(duì)動(dòng)態(tài)開(kāi)辟空間的越界訪(fǎng)問(wèn),使用free釋放非動(dòng)態(tài)開(kāi)辟的空間,使用free釋放動(dòng)態(tài)內(nèi)存中的一部分,對(duì)同一塊動(dòng)態(tài)開(kāi)辟的空間,多次釋放,動(dòng)態(tài)開(kāi)辟空間忘記釋放。下面我們挨個(gè)來(lái)分析,刨析一下這些個(gè)常見(jiàn)的動(dòng)態(tài)內(nèi)存開(kāi)辟的問(wèn)題。

一、動(dòng)態(tài)內(nèi)存錯(cuò)誤

1.對(duì)NULL指針的解引用操作

代碼如下(示例):

錯(cuò)誤示例:
//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
 
	int* p = malloc(100000000000);
	//沒(méi)有對(duì)mollac函數(shù)的返回值做判空處理
		int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = 5;
	}
	
	return 0;
}
 
正確示例:
//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
 
	int* p = malloc(100000000000);
	if (p == NULL)
	{
		return 1;
	}
		int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = 5;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

2.對(duì)動(dòng)態(tài)開(kāi)辟空間的越界訪(fǎng)問(wèn)

代碼如下(示例):

錯(cuò)誤示例:
//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
 
	int* p = (int*)malloc(10*sizeof(int));
	if (p == NULL)
	{
		return 1;
	}
		int i = 0;
		//越界訪(fǎng)問(wèn)
	for (i = 0; i < 40; i++)//malloc函數(shù)只是開(kāi)辟了十個(gè)整型的空間,這里卻要訪(fǎng)問(wèn)四十個(gè)元素。
	{
		*(p + i) = 5;
	}
	for (i = 0; i < 40; i++)
	{
		printf("%d ", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}
 
正確示例:
//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
 
	int* p = (int*)malloc(10*sizeof(int));
	if (p == NULL)
	{
		return 1;
	}
		int i = 0;
		
	for (i = 0; i < 10; i++)
		*(p + i) = 5;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", p[i]);
	}
	free(p);
	p = NULL;
	return 0;
}

3.使用free釋放非動(dòng)態(tài)開(kāi)辟的空間

代碼如下(示例):

//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
	int arr[10] = { 0 };//棧區(qū)
	int* p = arr;
	free(p);//使用free釋放非動(dòng)態(tài)開(kāi)辟的空間
	p = NULL;
	return 0;
}

4.使用free釋放動(dòng)態(tài)內(nèi)存中的一部分

代碼如下(示例):

 
//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
	int* p = malloc(10 * sizeof(int));
	if (p == NULL)
	{
		return 1;
	}
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		*p++ = i;//1:p一直往后走之后沒(méi)人知道起始空間的位置在哪,2:p釋放的只是后面空間的一部分,前面的空間并沒(méi)有得到釋放。
	}
	free(p);
	p = NULL;
	return 0;
}

5.對(duì)同一塊動(dòng)態(tài)內(nèi)存動(dòng)態(tài)開(kāi)辟的空間多次釋放

代碼如下(示例):

//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
	int* p = malloc(10 * sizeof(int));
	//使用
	//釋放
	free(p);
	//再次釋放
	free(p);//free要是傳的是空指針什么事都不會(huì)發(fā)生。
	p = NULL;
	return 0;
}

6.動(dòng)態(tài)開(kāi)辟的空間忘記釋放(容易造成內(nèi)存泄露,比較嚴(yán)重)

代碼如下(示例):

void test()
{
	int* p = malloc(10 * sizeof(int));
	if (p == NULL)
	{
		return 1;
	}
	//使用
	//忘記釋放
}
 
//動(dòng)態(tài)內(nèi)存開(kāi)辟
int main()
{
	test();
	return 0;
}

二、動(dòng)態(tài)內(nèi)存錯(cuò)誤面試題分析

1.NULL指針傳參不取地址傳的也是一份臨時(shí)拷貝

例題分析:
 
void GetMemory(char* p)
{
	p = (char*)malloc(100);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
}
 
int main()
{
	test();
	return 0;
}

程序運(yùn)行結(jié)果:

拷貝不成功,程序直接掛掉。

原因分析:

str傳給GetMemory函數(shù)的時(shí)候是值傳遞,所以GetMemory函數(shù)的形參p是str的一份臨時(shí)拷貝。
在GetMemory函數(shù)內(nèi)部動(dòng)態(tài)申請(qǐng)空間的地址,存放在P中,不會(huì)影響外面str,所以當(dāng)GetMemory函數(shù)返回
之后,str任然是NULL指針,所以strcpy會(huì)失敗。
當(dāng)GetMemory函數(shù)返回之后,形參p銷(xiāo)毀,使得動(dòng)態(tài)開(kāi)辟的100個(gè)字節(jié)存在內(nèi)存泄漏。

?正確代碼:

//第一種改法:
 
char* GetMemory(char* p)
{
	p = (char*)malloc(100);
	return p;
}
void test(void)
{
	char* str = NULL;
	str = GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}
 
int main()
{
	test();
	return 0;
}
 
 
//第二種改法:
 
char* GetMemory(char** p)
{
	*p = (char*)malloc(100);
}
void test(void)
{
	char* str = NULL;
	GetMemory(&str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}
 
int main()
{
	test();
	return 0;
}

2.局部變量和形式參數(shù)存在于棧上

代碼如下(示例):

//例題分析:
 
char* GetMemory(void)
{
	char p[] = "hello world";
	return p;
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
 
int main()
{
	test();
	return 0;
}

程序運(yùn)行結(jié)果:

打印不成功,打印的都是隨機(jī)值

原因分析:

GetMemory函數(shù)內(nèi)部創(chuàng)建的數(shù)組是在棧區(qū)上創(chuàng)建的
出了函數(shù),p的數(shù)組的空間就還給了操作系統(tǒng)
返回的地址是沒(méi)有實(shí)際意義的,如果通過(guò)返回的地址,去訪(fǎng)問(wèn)內(nèi)存就是非法訪(fǎng)問(wèn)內(nèi)存。

?正確代碼:

char* GetMemory(void)
{
	static char p[] = "hello world";
	return p;
}
void test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
 
int main()
{
	test();
	return 0;
}

3.動(dòng)態(tài)內(nèi)存開(kāi)的空間記得free釋放掉

代碼如下(示例)

void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
}
int main()
{
	test();
	return 0;
}

錯(cuò)誤分析:

申請(qǐng)的動(dòng)態(tài)內(nèi)存空間使用完之后沒(méi)有及時(shí)free釋放掉。

正確代碼:

void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
	free(str);
	str = NULL;
}
int main()
{
	test();
	return 0;
}

4.非法訪(fǎng)問(wèn)內(nèi)存

代碼如下(示例)

void test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}
int main()
{
	test();
	return 0;
}

錯(cuò)誤分析:

申請(qǐng)的空間已經(jīng)free釋放還給操作系統(tǒng)了,及時(shí)str還記得這塊空間的起始地址,但是也不能訪(fǎng)問(wèn),屬于非法訪(fǎng)問(wèn)內(nèi)存空間。
free完之后要及時(shí)把str置成NULL指針。

正確代碼:

void test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
	str = NULL;
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}
int main()
{
	test();
	return 0;
}

總結(jié):

上述給大家簡(jiǎn)單介紹了動(dòng)態(tài)內(nèi)存開(kāi)辟常見(jiàn)的幾種問(wèn)題,也分析了往年的幾道面試題里面的錯(cuò)誤,讓我們加深了對(duì)這一章的理解,后續(xù)自己使用的時(shí)候可以有效的規(guī)避掉這些問(wèn)題。相信大家都學(xué)會(huì)了。如果上述文章有任何問(wèn)題?,歡迎大佬們提出質(zhì)疑,我會(huì)虛心學(xué)習(xí)和改正,最重要的是能共同進(jìn)步,共同成長(zhǎng),學(xué)習(xí)好編程。

到此這篇關(guān)于C語(yǔ)言 動(dòng)態(tài)內(nèi)存開(kāi)辟常見(jiàn)問(wèn)題解決與分析流程的文章就介紹到這了,更多相關(guān)C語(yǔ)言 動(dòng)態(tài)內(nèi)存開(kāi)辟內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

凉山| 长乐市| 谢通门县| 咸阳市| 陆河县| 广饶县| 固原市| 赫章县| 肥西县| 罗平县| 玉田县| 西平县| 六盘水市| 房山区| 江都市| 宁明县| 舟曲县| 通辽市| 临海市| 西乌| 兴安盟| 扶余县| 上犹县| 兴国县| 清河县| 柳林县| 衡水市| 彭泽县| 桑植县| 高唐县| 宜昌市| 宁海县| 南皮县| 汶川县| 许昌县| 南安市| 深泽县| 江城| 昭平县| 全椒县| 定兴县|