当指针作为函数的形参时,不要用该指针去申请动态内存。网上有下面的例子:
void GetMemory(char *p, int num)
{
p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
char *str = NULL;
GetMemory(str, 100); // str 仍然为 NULL
strcpy(str, "hello"); // 运行错误
}
在实际应用中,笔者编写了类似的例子,用形参指针去调用malloc函数,使用gcc编译,编译时不会报错,但是运行时会报段错误,产生段错误的因素很多,但本次运行的段错误确实跟形参指针调用malloc函数有关,当然也不是说形参指针不能调用malloc函数去申请动态内存,只是不能使用上述例子中的方式。
c语言中函数参数传递都是值传递,值传递分为数值传递和指针传递,因此指针传递也是一次赋值拷贝的过程。对于传入的指针参
数 p 来说,编译器会为该参数创建一个临时副本,例如 _p。函数体中只是修改了形参_p的内容,对于实参p没有任何影响。
如果想要在调用函数中申请内存,笔者在网上找到了两种方式:
1. 双重指针
void GetMemory(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100); //注意是&str
strcpy(str, "hello");
free(str);
}
2.参数返回申请的内存
char * GetMemory( int num)
{
char *p = (char *)malloc(sizeof(char) * num);
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory(100); //注意是&str
strcpy(str, "hello");
free(str);
}
3. 结合c++的引用
总体测试如下:
//一级指针,失败
void test0(float* p)
{
p = (float*)malloc(sizeof(float));
*p = 6.6;
}
// 二级指针成功
void test1(float** p)
{
*p = (float*)malloc(sizeof(float));
**p = 3.14;
}
// 返回指针成功
float* test2()
{
float*p = (float*)malloc(sizeof(float));
*p = 4.14;
return p;
}
// 结合c++的引用成功
void test3(float*& p)
{
p = (float*)malloc(sizeof(float));
*p = 5.14;
}
int main(){
float a = 3.3;
float* p0 = &a;
test0(p0);
printf("*p0 = %f\n", *p0);
free(p0);
float* p1 = nullptr;
test1(&p1);
printf("*p1 = %f\n", *p1);
free(p1);
float* p2 = nullptr;
p2 = test2();
printf("*p2 = %f\n",*p2);
free(p2);
float* p3 = nullptr;
test3(p3);
printf("*p3 = %f\n", *p3);
free(p3);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)