C语言中函数返回局部变量的方法

来源:互联网 发布:lightroom mac 2017 编辑:程序博客网 时间:2024/05/16 06:21

对于局部变量,首先应该明确:其作用域是在函数内部,函数返回则变量被释放。而函数返回局部变量的情况,一般来说分两种:返回变量的值和返回指针。直接返回变量的值,一般来说是没有问题的。经常出错的是返回指针的情况。

返回指针的情况,我们先看两个例子:

1.

char *gen_local_variable(){    char *local_variable = "hello world!";    return local_variable;}......tmp = gen_local_variable();......
2.
char *gen_local_variable(){    char local_variable[] = "hello world!";    return local_variable;}......tmp = gen_local_variable();......

这两种情况,哪个对哪个错?

答案是:1对,2错。

让我们来分析一下为什么。对于1,函数中定义了局部指针local_variable,并且指向字符串"hello world!"。这里,我们要明确:"hello world!"是字符串常量,其存放的位置在只读存储区。因此,在函数gen_local_variable()结束后,local_variable指向的空间是不释放的。所以,这里是没有问题的。

反观2中,定义了字符数组local_variable,其存放的位置是在栈上。很明显,当函数执行完之后,指针所指向的栈的空间已经释放了。因此,就不难理解为什么会出错了。

下面我们讨论一下,如何解决上面的问题。方案有如下几种:

1. 使用全局变量

这种方法简单易用,但是缺点在于任何人都有可能在任何时候修改这个全局变量,

2. 使用静态数组,例如

char *gen_local_variable(){    static char local_variable[] ;    ......    return local_variable;}

这样可以防止任何人修改这个数组,但是该函数的下一次调用将覆盖这个数组的内容,所以调用者必须在此之前使用或者备份数组的内容。和全局变量一样,大段的缓冲区闲置不用,是很浪费内存空间的。

3. 显式分配一些内存,保存返回的值。例如:

char *gen_local_variable(){    char *local_variable = malloc(100);    ......    return local_variable;}

这个方法具有静态数组的优点,而且在每次调用时都创建一个新的缓冲区,所以函数以后的调用都不会覆盖之前的返回值。它适用于多线程的代码。其缺点在于:程序员必须承担内存管理的任务。人们很容易忘记释放已分配的内存,从而产生令人难以置信的bug。

4. 调用者分配内存来保存函数的返回值。这也许是最好的解决方案。

void gen_variable(char *variable, int size){    char *local_variable;    ......    strncpy(variable, local_variable, size);}buffer = malloc(size);gen_variable(buffer, size);......free(buff);

在同一代码块中进行malloc和free操作,内存管理是最简单的了。


以上是我在看《C专家编程》中的一些体会,欢迎各位的指正。




原创粉丝点击