void GetMemery(char *p){
p = (char *)malloc(100);
}
void Test(){
char *str = NULL;
GetMemory(str);
strcpy(str,"hello world");
printf(str);
}
int main(){
Test();
}
請問運行test函數會有什麼樣的結果?
下面是在windows下vs2013編譯器的結果:程序崩潰
因爲GetMemory方法並不能傳遞動態內存!test函數中的str一直都是null;strcpy將使程序崩潰
之所以不能傳遞動態內存,是因爲在使用指針作爲參數傳遞進另外一個函數的時候,如果在這個函數中修改了指針參數的地址,原來的指針還是不變的,因爲在函數中調用另外一個函數並且將指針作爲參數進行傳遞時,會將原來的指針複製一份,並且將這個副本當做實參傳遞進test函數,並且將其壓進函數棧,在test函數中所進行的修改地址的操作只會修改指針副本的地址,對原來的指針是不會有影響的!正如一個經典的swap函數
swap(int *a,int *b){
int *temp = a;
a = b;
b = temp;
}
如果用上面這段程序來對兩個數進行交換的話,那麼是不會成功的,注意我是用的一個指針類型的temp,相當於在swap函數中修改了a,b的地址,所以根據上面所說的原理,是不能交換兩個數的,如果想要交換,那麼將temp的類型改爲int類型,而不是Int指針類型,就ok。
如果想要在函數體內修改指針的地址,不能直接修改指針的地址,而應該傳入一個指針類型的引用或者指針的指針,兩者都是二級指針,就像下面這段代碼!
#include <stdio.h>
#include <iostream>
using namespace std;
//直接在指針上分配動態內存,不可取,程序崩潰
void GetMemory(char *p){
p = (char *)malloc(100);
}
//使用指針類型的引用來作爲參數進行傳遞,這樣是可行的,輸出helloworld
void GetMemory2(char *&p){
p = (char*)malloc(100);
}
//使用指針的指針來進行參數的傳遞,這樣也是可行的,輸出helloworld
void GetMemory3(char **p){
*p = (char*)malloc(100);//此處要直接給二級指針所指向的一級指針所指向的字符數組直接分配內存,因爲我們需要的是在一級指針所指向的內存中複製helloworld進去
}
void Test(){
char *str = NULL;
//GetMemory(str);
//GetMemory2(str);
char **str2 = &str;
GetMemory3(str2);
strcpy(str,"hello world");
printf(str);
}
int main(){
Test();
}