从函数返回一个静态变量

时间:2014-01-09 10:48:36

标签: c

以下代码:

#include <stdio.h>
#include "string.h"

int main() { 
    char *s ; 
    char *fun() ;   
    s = fun() ;    
    printf ("%s",s) ;
    return 0; 
} 

char *fun() {  
    char buffer[30] ;
    strcpy ( buffer, "RAM - Rarely Adequate Memory" ) ; 
    return ( buffer ) ;  
} 

每当缓冲区的大小发生变化并且没有提供所需答案时,都会产生意外结果。

通过制作字符buffer[30] static,代码会打印出正确的"RAM-Rarely Adequate Memory" 静电如何产生影响?

6 个答案:

答案 0 :(得分:3)

一旦离开声明它们的块,

(自动)局部变量就会被销毁。保持对它们的引用与保持指向解除分配的内存块的指针一样错误。

静态(本地)变量与声明它们的程序具有相同的生命周期。

实现方面,静态变量与全局变量在同一空间中分配 在语义上,它仍然只在声明它的块内可见,但它保留其声明范围之外的值。

但是,请注意。保留对静态变量的引用可能会产生令人不快的副作用。

例如,对函数的每次调用都会将字符串重置为其初始值,因此如果调用者不希望任何其他代码段能够使用该值,那么调用者应该创建自己的副本。他们从你的职能中获得了。

答案 1 :(得分:2)

您将返回一个本地变量,该变量触发未定义的行为。 char buffer[30]是一个堆栈变量,所以当函数退出时,它会超出范围,并被清理。

使其成为static意味着当函数退出时它不会超出范围,因此可以正常工作。

在C中,人们通常会通过传入缓冲区来写入:

来解决这个问题
void fun(char *buffer, size_t len)
{
    // Write some stuff into buffer
}

在C ++中,使用std::string

答案 2 :(得分:1)

如果没有static,只要函数buffer终止,变量fun就会超出范围。然后main例程保留一个指向已失效变量的指针,并且取消引用它会导致未定义行为

答案 3 :(得分:1)

buffer是一个局部变量,它会在fun结束时被销毁。

如果bufferstatic,则始终在程序中。

如果您希望fun返回一个数组,则可以使用动态内存。

#include<stdio.h>
#include"string.h"

int main( ){

    char *s;    
    char *fun();

    s = fun();    
    printf ("%s",s);

    // in c pure 
    //free(s);
    // in c++
    delete s;
}


char *fun(){         
    // in c pure
    //char * buffer = (char*) malloc(30*sizeof(char));        
    // in c++
    char *buffer = new char[30];

    strcpy ( buffer, "RAM - Rarely Adequate Memory" );        
    return ( buffer ) ;    
} 

答案 4 :(得分:1)

首先,不应返回指向局部变量的指针。

其次,auto局部变量将在代码块(函数)退出后立即消失。但是static局部变量将保留在那里直到整个程序结束。出于同样的原因,您可以在下次进入该代码块时访问该static局部变量。

答案 5 :(得分:0)

没有buffer的{​​{1}}放置在处理器的stack上。当static结束时,将释放用于此函数的堆栈内存。

但是这种释放实际上并没有改变这些使用过的堆栈内存位置的内容。这意味着您复制到fun的字符串最初仍然存在。

随着程序的进展,这个释放的堆栈空间(最初由buffer使用)将被用于其他东西。但是很难说这会发生什么,因为这完全取决于编译器计划如何使用堆栈空间。

从理论上讲,你的程序可以很好地打印出buffer;当堆栈的这一部分没有被覆盖时。所以实际上你很幸运,因为你可能有一个潜伏的错误,可以在稍后阶段咬人(例如在你开始向RAM - Rarely Adequate Memory添加代码之后,或者更改了编译器选项。)