一般情況,子函數中動態申請內存,將地址返回給主函數,理論上應該也是可以的,需要子函數返回動態內存地址,主函數實參是相應的地址變量即可。只不過,主函數實參傳入子函數之前,可能會將指針置空,那么,子函數就不能動態申請內存了。
如下例子:
C語言進階---動態內存管理_c語言怎么遍歷動態申請里面的內容-CSDN博客
4.幾個經典的面試題
4.1 題目1:
void Getmemory(char* p)//形參是實參的一份臨時拷貝 p是指針變量 p指向NULL *p是NULL
{p = (char*)malloc(100);//p由指向NULL 變為指向malloc開辟空間的起始地址
}
void Test(void)
{char* str = NULL;GetMemory(str);//傳的是實參strcpy(str, "helllo world");printf(str);
}
//程序會崩潰無法打印
更正:通過傳實參的地址來找到實參在內存當中的位置然后再改變實參的值:
void GetMemory(char** p)//char**p接收str的地址,是一個二級指針
{*p = (char*)malloc(100);//*p==str 由指向NULL 變為指向malloc開辟空間的起始地址
}
void Test(void)
{char* str = NULL;GetMemory(&str);//轉str的地址strcpy(str, "helllo world");printf(str);free(str);str = NULL;
}
int main()
{Test();return 0;
}
//程序會正常打印"hello world"
另一個傳地址的例子:
4.2題目2:
返回棧空間問題:
char* GetMemory(void)
{char p [] = "hello world";//棧空間開辟數組return p;//p放在寄存器當中,這個函數可以成功返回數組名p,也就是數組的首元素地址}
void Test(void)
{char* str = NULL;str = GetMemory();printf(str);
}
int main()
{Test();return 0;
}
//棧空間在用完之后會被系統回收,因此創建的數組p在GetMemory調用完之后就已經被銷毀無法使用了
//str屬于是野指針去訪問了一塊被銷毀的空間,因此會打印一些隨機值
改為:
int* test()
{int a = 10;return &a;//a的地址被存放在寄存器當中
}
int main()
{int* p = test();//p接收到a的地址printf("%d\n", *p);//p已經是野指針 打印10 因為調用test的棧空間還沒有被覆蓋printf("%d\n", *p);// 打印隨機值 有一次調用test函數,棧空間被新隨機值給覆蓋return 0;
}
另外,上面所說子函數動態申請內存給主函數用,主函數在使用完要釋放。釋放后最好置空,否則,其是個野指針,可能會導致錯誤。
4.3題目3:
void GetMemory(char** p, int num)
{assert(*p);*p = (char*)malloc(num);
}
void tset(void)
{char* str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);//free釋放free(str);str = NULL;
}
int main()
{test();return 0;
}
改正:
void test(void)
{char* str = (char*)malloc(100);strcpy(str, "hello");free(str);//free釋放str = NULL;//置空if (str != NULL){strcpy(str, "world");printf(str);//無法打印}
}
int main()
{test();return 0;
}