您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
第35讲-从函数或方法返回内存
发布时间:2021-05-20 22:28:31编辑:雪饮阅读()
C++在delete指针后要赋值为NULL
C++标准规定:delete空指针是合法的,没有副作用。
所以我们在Delete指针后赋值为NULL或0是个好习惯。对一个非空指针delete后,若没有赋NULL,若再次delete的话
有可能出现问题。
一个具体的实例如:
#include <iostream>
int *newInt(int value){
int *myInt=new int;
*myInt=value;
return myInt;
};
int main(){
int *x=newInt(20);
std::cout<<*x;
delete x;
/*
delete是释放指针指向的内存
并不是指针本身所占有的内存
所以delete后,指针的还是指向那块区域,并未清0,
所以如果下次用到,就会发生xxx空间不能访问的异常。
所以delete后要赋值为空
有发现在gcc下,可以delete多次。
一个指针delete多次是一种不好的行为,但C++语言并没有规定对于不好的行为都要报错。
delete多次一个指针,出不出问题取决于编译器的处理,delete多次空指针是没问题的。
不过还是建议delete之后置为NULL比较好
*/
x=NULL;
return 0;
}
编译运行效果如:
20
Process returned 0 (0x0) execution time : 0.030 s
Press any key to continue.
上面这个程序同时也教会了我们如何从函数或方法返回内存(指针),如果我们函数要返回的不是一个标量,则该技巧会非常有用的。
为什么不应该让函数返回一个指向局部变量的指针?
当然返回动态分配的内存指针是没有问题的
返回由malloc动态分配的内存指针。这种情况是合法的,但它假设调用者会释放动态分配的内存。在这种情况下通常会有另一个函数提供释放内存的功能。
但是普通局部变量不能以指针返回。
返回指向普通局部变量的指针。局部变量占用的内存会在函数返回时被系统自动回收,因此系统可以随时将其它数据写入这块内存。在这种情况下函数可以编译通过,但不能保证运行正确。(你返回了一个指向该局部变量的指针,但是该局部变量已经被释放了,那么有可能有其它数据被填充到该指针所指向的内存,这样就会造成后面使用该指针带来的隐患)
那么如果我们想要对一个函数内部的局部变量进行操作,比如最常见的变量交换,那么需要怎么做呢?
我们需要用到传址调用。
一个实例如:
#include <iostream>
void swap(int *x,int *y){
#if 0
int temp;
temp=*x;
*x=*y;
*y=temp;
std::cout<<"QQ音乐,音乐你的生活!";
#endif
*x^=*y;
*y^=*x;
*x^=*y;
}
int main(){
int a=3,b=5;
swap(&a,&b);
std::cout<<"a="<<a<<"\n";
std::cout<<"b="<<b<<"\n";
return 0;
}
编译并运行结果如:
a=5
b=3
Process returned 0 (0x0) execution time : 0.077 s
Press any key to continue.
函数指针
函数指针是指向函数首地址的指针变量称为函数指针。
我们来看看如下实例吧:
#include <stdio.h>
int fun(int x,int y);
fun(int x,int y){
int z;
z=(x>y) ? x:y;
return (z);
};
int main(){
int i,a,b;
/*
定义函数指针
这里小甲鱼原来给的声明是这样的int (*p)();
但是这里根本跑不了,还是去参考了一下菜鸟教程,调整成下面这样的
或许甲鱼的那种写法在以前可以吧,但是还是觉得甲鱼有点坑呢
因为他视频中他这个实例就没有自己跑一下
*/
int (*p)(int,int);
scanf("%d",&a);
/*
函数指针指向函数fun
这里他同样坑,他原来的语句是:
p=fun
没有带取址操作符,对于一个指针类型而言。。。。
这个错误也未免。。。
*/
p=&fun;
printf("请输入十个数字");
for(i=0;i<10;i++){
scanf("%d",&b);
//通过函数指针p调用函数
a=(*p)(a,b);
}
printf("the Max Number is:%d",a);
return 0;
}
编译并运行结果如:
关键字词:函数,指针,函数指针
上一篇:第34讲-动态数组
下一篇:第36讲-副本构造器