从函数或方法返回内存
动态内存的另一个常见用途是让函教申请并返回一个指向内存块的指针。掌握这个技巧很重要,尤其是在你打算使用由别人编写的库文件时。如果不知道这个技巧,就只能让函数返回一个简单的标量值,如整型、浮点型或字等型。换句话说,它既不能返回一个以上的值,也不能返回数组之类比较复杂的数据结构。可以这样说,只要你想让函数返回的东西不是一个简单的值,就需要学习本讲内容。
这个技巧的基本思路并不复杂:在函数里调用new 语句为某种对象或某种基本数据类型分配一块内存(在堆里分配,不是栈),再把那块内存的地址返回给程序的主代码,主代码将使用那块内存并在完成有关操作后立刻释放。请看代码段:segment.cpp
#include<iostream> int *newInt(int value); int main() { int *x = newInt(20); std::cout<< *x; delete x; x = NULL; return 0; } int *newInt(int value) { int *myInt = new int; *myInt = value; return myInt; }
为什么不应该让函数返回一个指向局部变量的指针?
我们曾讨论过变量作用城的概念:函数或方法有它们自己的变量,这些变量只能在这个函数的内部使用,这些变量我们成为局部变量(local variable)。我们又知道如何利用指针在某个函数内部改变另一个函数的局部变量的值(例如传址调用)。
//传址引用 #include<iostream> void swap(int *x, int *y); int main() { int a, b; a = 3; b = 5; swap(&a, &b); std::cout<< "a = " << a << " "; std::cout<< "b = " << b << " "; return 0; } void swap(int *x, int *y) { #if 0 int temp; temp = *x; *x = *y; *y =temp; #endif //上述代码换种形式书写: *x ^= *y; *y ^= *x; *x ^= *y; }
这是绕开变量作用域的一种手段,在某些场合是非常必要的。
任何一个函数都不应该把它自己的局部变量的指针作为它的返回值!因为局部变量在栈里,函数结束自动会释放。如果你想让一个函数在不会留下任何隐患的情况下返回一个指针,那它只能是一个动态分配的内存块的基地址。
函数指针和指针函数
今天的知识点很容易让大家联想起C语言的指针函数,这里就借此之便给大家继续探讨下很容易混浴的两个概念:函数指针和指针函数。
函数指针:指向函教首地址的指针变量称为函数指针(举例如下)。
#include <stdio.h> int fun(int x, int y); int main() { int i, a, b; int (*p)(); /* 声明函数指针 */ scanf("%d", &a); p = fun; /* 给函数指针p赋值,使它指向函数f */ printf("Please input ten numbers: "); for(i = 0; i < 10; i++) { scanf("%d", &b); a = (*p)(a, b); /* 通过指针p调用函数f */ } printf("The max number is %d",a); return 0; } int fun(int x, int y) { int z; z = (x > y) ? x : y; return(z); }
指针函数:一个函教可以蒂回一个整型数据的值,字类型值和突型类型的值,还可以带回指针类型的数据重其指向某个地址单元。举例如下。
#include<iostream> int *newInt(int value); int main() { int *x = newInt(20); std::cout<< *x; delete x; x = NULL; return 0; } int *newInt(int value) { int *myInt = new int; *myInt = value; return myInt; }