使用指針作爲函數返回值和參數的問題總結

1、內存分配方式有三種

(1)從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static變量。


(2)在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指              令集中,效率很高,但是分配的內存容量有限。


(3)從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。動態內存的生存            期由我們決定,使用非常靈活,但問題也最多。


2、使用指針做函數返回值

錯誤1:使用棧內存返回指針。因爲棧內存將在調用結束後自動釋放,從而主函數使用該地址空間將很危險。
例如:指針pcStr將指向一個未知的內存內容。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static char *GetWord()
{
char pcWord[32] = "hello word!";
return pcWord;
}

int main(int argc, char *argv[])
{
char *pcStr = NULL;
pcStr = GetWord();//出錯! 得到一塊已釋放的內存
printf("pcStr = %s\n", pcStr);

return 0;
}

正確的使用方法是使用堆內存返回指針,但是要注意防止內存泄露,該內存使用完畢後要記得釋放
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static char *GetWord()
{
char Word[32] = "hello word!";
char *pcWord = NULL;
pcWord = malloc(32 * sizeof(char));
if(NULL == pcWord)
{
printf("pcWord malloc memeory failed.\n");
return NULL;
}
strcpy(pcWord, Word);

return pcWord;
}

int main(int argc, char *argv[])
{
char *pcStr = NULL;
pcStr = GetWord();
printf("pcStr = %s\n", pcStr);
free(pcStr);//記得釋放內存 防止內存泄露
pcStr = NULL;//避免形成野指針
return 0;
}

3、使用指針作函數參數

在C語言中,形參只是繼承了實參的值,是另外一個量(返回值也是同理,傳遞了一個地址值(指針)或實數值),形參的改變並不能引起實參的改變。
錯誤1:直接使用形參分配內存,因爲實參的值並不會改變,如下則實參一直爲NULL

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static void MallocWordMem(char *pcWord)
{
pcWord = malloc(32 * sizeof(char));
if(NULL == pcWord)
{
printf("pcWord malloc memeory failed.\n");
return ;
}
}

int main(int argc, char *argv[])
{
char *pcStr = NULL;
char cWord[32] = "hello word!";

MallocWordMem(pcStr);
strcpy(pcStr, cWord);
printf("pcStr = %s\n", pcStr);
free(pcStr);//記得釋放內存 防止內存泄露
pcStr = NULL;//避免形成野指針
return 0;
}
程序運行提示段錯誤。


2、通過指針是可以傳值的,因爲此時該指針的地址是在主函數中申請的棧內存,我們通過指針對該棧內存進行操作,從而改變了實參的值。(這個就不舉例說明了。)



3、可以採用指向指針的指針來進行在調用函數中申請內存

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
char c = 'A';
char *pc = &c;
char **ppc = &pc;


printf("c addr = %p, c = %c\n", &c, c);
printf("pc addr = %p, pc = %p, *pc = %c\n", &pc, pc, *pc);
printf("ppc addr = %p, ppc = %p, *ppc = %p, **ppc = %c\n", &ppc, ppc, *ppc, **ppc);


return 0;
}
執行結果如下:
xzg@byxc-PDSML:~$ ./1
c addr = 0xbfc19adf, c = A
pc addr = 0xbfc19ad4, pc = 0xbfc19adf, *pc = A
ppc addr = 0xbfc19ad8, ppc = 0xbfc19ad4, *ppc = 0xbfc19adf, **ppc = A
變量c的地址爲0xbfc19adf,,內容時‘A’ ,
變量pc的地址是0xbfc19ad4,內容爲變量c的地址0xbfc19adf,內容地址指向的數據是‘A’

變量ppc的地址是0xbfc19ad8,內容是變量pc的地址,內容地址指向的數據是變量c的地址,內容指向的地址的地址的內容是‘A’


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static void MallocWordMem(char **pcWord)
{
*pcWord = malloc(32 * sizeof(char));
if(NULL == pcWord)
{
printf("pcWord malloc memeory failed.\n");
return ;
}
}

int main(int argc, char *argv[])
{
char c = 'A';
char *pc = NULL;
char **ppc = &pc;


pc = &c;
printf("c addr = %p, c = %c\n", &c, c);
printf("pc addr = %p, pc = %p, *pc = %c\n", &pc, pc, *pc);
printf("ppc addr = %p, ppc = %p, *ppc = %p, **ppc = %c\n", &ppc, ppc, *ppc, **ppc);

MallocWordMem(ppc);
strcpy(pc, "abcd");
printf("pc = %s\n", pc);


return 0;
}
程序運行結果如下:
xzg@byxc-PDSML:~$ ./1
c addr = 0xbfac126f, c = A
pc addr = 0xbfac1264, pc = 0xbfac126f, *pc = A
ppc addr = 0xbfac1268, ppc = 0xbfac1264, *ppc = 0xbfac126f, **ppc = A
pc = abcd
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章