C語(yǔ)言動(dòng)態(tài)內(nèi)存泄露常見(jiàn)問(wèn)題內(nèi)存分配改進(jìn)方法詳解
一、例題
試問(wèn)該段代碼能打印什么,或者不能打印什么,說(shuō)出理由
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> void getmemory(char*p) { p = (char*)malloc(100); } void test() { char*str = NULL; getmemory(str); strcpy(str, "hello world"); printf("%s",str); } int main() { test(); return 0; }
這段代碼乍一看好像沒(méi)有啥問(wèn)題,test函數(shù)進(jìn)去創(chuàng)建一個(gè)str嘛,然后str傳給getmemory函數(shù),開(kāi)辟一塊空間,然后hello world這字符串放進(jìn)開(kāi)辟的空間里,然后打印str也就是hello world嘛。
但是,上面的思路是完全錯(cuò)誤的,代碼完全無(wú)法運(yùn)行,解釋如下:
- 第一:你str傳到getmemory函數(shù)里,p開(kāi)辟一個(gè)空間,被開(kāi)辟的空間和str沒(méi)有關(guān)系
(傳值調(diào)用和傳址調(diào)用的區(qū)別)
- 第二:你getmemory函數(shù)出來(lái)之后,開(kāi)辟的空間沒(méi)有釋放掉,而且你p由于函數(shù)的結(jié)束已經(jīng)銷毀了,p銷毀之后再也無(wú)法找到開(kāi)辟的空間,造成內(nèi)存泄漏
就比如p是一個(gè)警察頭子,開(kāi)辟的空間是臥底,只有p知道那個(gè)臥底,你現(xiàn)在警察頭子死了,再也沒(méi)法證明臥底是臥底了
也就是說(shuō)p消失后,沒(méi)辦法再對(duì)開(kāi)辟的空間進(jìn)行釋放,這時(shí)就會(huì)造成內(nèi)存泄露
二、2種改進(jìn)方法
法1:二級(jí)指針(傳址調(diào)用)
代碼如下(示例):
void getmemory(char**p) { *p = (char*)malloc(100);//p是str地址,*p是str } void test() { char*str = NULL; getmemory(&str); strcpy(str, "hello world"); printf("%s",str); free(str); str = NULL; } int main() { test(); return 0; }
因?yàn)橹暗膫髦嫡{(diào)用沒(méi)法讓p和str建立聯(lián)系,那我們就傳地址,開(kāi)辟一塊空間出來(lái)賦給*p
要注意的是,p是str地址嘛,*p也就是str,到這里,str掌握了新開(kāi)辟空間的控制權(quán)。然后getmemory函數(shù)出來(lái),進(jìn)行strcpy和printf操作,最后不要忘記free掉原先的空間。
法2:返回指針
代碼如下(示例):
char* getmemory(char*p) { p = (char*)malloc(100); return p; } void test() { char*str = NULL; str=getmemory(str); strcpy(str, "hello world"); printf("%s", str); free(str); str = NULL; } int main() { test(); return 0; }
因?yàn)檫@里是開(kāi)辟了一塊空間給指針p管理嘛,str和p沒(méi)有建立聯(lián)系,那你直接函數(shù)返回p這個(gè)指針然后賦值給str即可,隨后操作和方法1一樣
總結(jié)
本文介紹了動(dòng)態(tài)內(nèi)存分配的常見(jiàn)例題及兩種改進(jìn)方法,讀者需要理解為何會(huì)發(fā)生內(nèi)存泄露和傳值與傳址調(diào)用的區(qū)別就可以熟練解決這類問(wèn)題。以上,祝讀者學(xué)習(xí)愉快~希望大家以后多多支持腳本之家!
相關(guān)文章
C/C++?Qt?TableDelegate?自定義代理組件使用詳解
TableDelegate自定義代理組件的主要作用是對(duì)原有表格進(jìn)行調(diào)整,本文主要介紹了QT中TableDelegate?自定義代理組件的使用教程,感興趣的朋友可以了解一下2021-12-12C++中overload,override,overwrite的區(qū)別詳細(xì)解析
以下是對(duì)C++中overload,override,overwrite的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下2013-09-09仿現(xiàn)代C++智能指針實(shí)現(xiàn)引用計(jì)數(shù)
這篇文章主要為大家詳細(xì)介紹了如何仿現(xiàn)代C++智能指針實(shí)現(xiàn)引用計(jì)數(shù),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2024-03-03C語(yǔ)言數(shù)組按協(xié)議存儲(chǔ)與按協(xié)議解析數(shù)據(jù)的實(shí)現(xiàn)
今天小編就為大家分享一篇關(guān)于C語(yǔ)言數(shù)組按協(xié)議存儲(chǔ)與按協(xié)議解析數(shù)據(jù)的實(shí)現(xiàn),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12c++字符串char[]數(shù)組分割split問(wèn)題
這篇文章主要介紹了c++字符串char[]數(shù)組分割split問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09C++實(shí)現(xiàn)簡(jiǎn)單計(jì)算器
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05C++的template模板中class與typename關(guān)鍵字的區(qū)別分析
這篇文章中我們來(lái)談一談C++的template模板中class與typename關(guān)鍵字的區(qū)別分析,同時(shí)會(huì)講到嵌套從屬名稱時(shí)的一些注意點(diǎn),需要的朋友可以參考下2016-06-06