以下代码:
#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"
静电如何产生影响?
答案 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
结束时被销毁。
如果buffer
为static
,则始终在程序中。
如果您希望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
添加代码之后,或者更改了编译器选项。)