指针做为参数注意事项
2014-09-16 15:35
148 查看
如果一个函数的参数是一个指针,不能用此指针去动态申请内存。
#include <stdio.h>
#include <iostream>
using namespace std;
void GetMemory(char *p,int size)
{
p = (char*)malloc(sizeof(char)*size); //申请内存空间
}
void Test()
{
char *str = NULL;
GetMemory(str,100); //str 任然是NULL
strcpy(str,"hello"); //运行报错
}
int main(void)
{
Test();
return 0;
}
发送错误是因为:GetMemory()函数中申请内存的时候,函数为参数申请了一个临时副本:_p=p,如果函数体内修改了副本的内容,那么也就修改了P的内容,这就符合了指针作为输出参数的原因,但是在这里,只是把副本_p的内存地址改变了,但是P没有被改变,所以不能返回。
解决办法就是使用“指向指针的指针”去申请内存。实例代码如下:
void GetMemory(char **p,int size)
{
*p = (char*)malloc(sizeof(char)*size); //申请内存空间
}
void Test()
{
char *str = NULL;
int n = 10;
GetMemory(&str, n);
strcpy(str,"hello");
cout<<str<<endl;
free(str);
}
还可以使用返回堆指针的形式(即通过返回值传递动态内存):
char* GetMemory(int size)
{
char *p = (char*)malloc(sizeof(char)*size); //申请内存空间
return p;
}
void Test()
{
char *str = NULL;
int n = 10;
str = GetMemory(n);
strcpy(str,"hello");
cout<<str<<endl;
free(str);
}
不要出现下面的情况:编译器报错,p只有在GetMemory()函数中有效,返回后p指向的对象的值被销毁,所以此时指向的值是乱码。
char* GetMemory(int size)
{
char *p[] = "hello world";
return p;
}
void Test()
{
char *str = NULL;
int n = 10;
str = GetMemory(n);
cout<<str<<endl;
free(str);
}
下面这种设计方法,虽然编译运行不会报错,但是这种设计方式错误的,因为char* p= “hello world”,申请了一个字符串常量,它存储在静态数据区,在程序的整个生命周期中恒定不变,无论什么时候调用,它返回的始终是同一个只读的内存块,都可以得到hello world的值。
char* GetMemory(int size)
{
char *p = "hello world";
return p;
}
void Test()
{
char *str = NULL;
int n = 10;
str = GetMemory(n);
cout<<str<<endl;
free(str);
}
函数参数的默认值只能出现在申明中,不能在定义体中出现,而且顺序只能是从右到左,有时候还会出现二义性。
void func(int a,int b=10);//申明的时候
void func(int a =10, int b, int c = 2);//报错,顺序只能从右到左
void func(int a, int b =10) //报错
{
}
#include <stdio.h>
#include <iostream>
using namespace std;
void GetMemory(char *p,int size)
{
p = (char*)malloc(sizeof(char)*size); //申请内存空间
}
void Test()
{
char *str = NULL;
GetMemory(str,100); //str 任然是NULL
strcpy(str,"hello"); //运行报错
}
int main(void)
{
Test();
return 0;
}
发送错误是因为:GetMemory()函数中申请内存的时候,函数为参数申请了一个临时副本:_p=p,如果函数体内修改了副本的内容,那么也就修改了P的内容,这就符合了指针作为输出参数的原因,但是在这里,只是把副本_p的内存地址改变了,但是P没有被改变,所以不能返回。
解决办法就是使用“指向指针的指针”去申请内存。实例代码如下:
void GetMemory(char **p,int size)
{
*p = (char*)malloc(sizeof(char)*size); //申请内存空间
}
void Test()
{
char *str = NULL;
int n = 10;
GetMemory(&str, n);
strcpy(str,"hello");
cout<<str<<endl;
free(str);
}
还可以使用返回堆指针的形式(即通过返回值传递动态内存):
char* GetMemory(int size)
{
char *p = (char*)malloc(sizeof(char)*size); //申请内存空间
return p;
}
void Test()
{
char *str = NULL;
int n = 10;
str = GetMemory(n);
strcpy(str,"hello");
cout<<str<<endl;
free(str);
}
不要出现下面的情况:编译器报错,p只有在GetMemory()函数中有效,返回后p指向的对象的值被销毁,所以此时指向的值是乱码。
char* GetMemory(int size)
{
char *p[] = "hello world";
return p;
}
void Test()
{
char *str = NULL;
int n = 10;
str = GetMemory(n);
cout<<str<<endl;
free(str);
}
下面这种设计方法,虽然编译运行不会报错,但是这种设计方式错误的,因为char* p= “hello world”,申请了一个字符串常量,它存储在静态数据区,在程序的整个生命周期中恒定不变,无论什么时候调用,它返回的始终是同一个只读的内存块,都可以得到hello world的值。
char* GetMemory(int size)
{
char *p = "hello world";
return p;
}
void Test()
{
char *str = NULL;
int n = 10;
str = GetMemory(n);
cout<<str<<endl;
free(str);
}
函数参数的默认值只能出现在申明中,不能在定义体中出现,而且顺序只能是从右到左,有时候还会出现二义性。
void func(int a,int b=10);//申明的时候
void func(int a =10, int b, int c = 2);//报错,顺序只能从右到左
void func(int a, int b =10) //报错
{
}
相关文章推荐
- C语言中“指针”作为“函数参数”时的注意事项
- C函数参数传递之指针传递要注意的事项
- CComPtr对象作为参数进行 1.值传递 2.引用传递 3.做为返回值的注意事项
- 带有指针参数的函数内给指针参数赋值时注意事项
- C 函数传递指针参数注意事项
- 使用指针作为函数参数的注意事项
- 指针做参数时注意事项
- chain redirect 参数传递注意事项
- ORACLE安装参数说明及注意事项!
- Android模拟器使用的快捷键、参数、注意事项
- COM接口指针使用的注意事项
- lucene3.0_和IndexWriter有关的几个参数设置及重建索引注意事项
- openscenegraph引用计数指针使用注意事项
- 智能指针auto_ptr使用注意事项
- 注意有指针参数的函数定义与函数实现 必须一致,编译器只检查是否是指针,而不管你的实参是几维指针
- 使用智能指针要注意的若干事项
- ASP.NET 参数传递,长度限制,及使用注意事项。
- SQLite 多参数插入注意事项 insert multiple parameters
- 指针注意事项(1)
- C++学习笔记-指针和引用的注意事项