2012-07-18 53 views
1

简单的程序,获取字符指针并把它放到输出。垃圾char *放到cout

char * get() 
{ 
    char ss [256]; 
    sprintf (ss,"%d",1); 
    return ss; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char *f = get(); 
    cout<<f; 
    char d[50] ; 
    cin>> d; 
} 

我在输出中只有垃圾。为什么?

+1

可能的重复[可以访问局部变量的内存超出其范围?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-范围) – 2012-07-18 15:55:39

回答

7

函数正在返回局部变量的地址。该代码具有未定义的行为,并提供不可预知的结果。

ss驻留在堆栈上,函数get()返回指向它的指针。

char * get() 
{ 
} // Life time of ss ends here 

改为使用std::string

+1

小调。我使用“指针”而不是“引用”,因为在C++中,“引用”有其特定的含义。 – 2012-07-18 15:13:28

+0

@DesmondHume同意。 – Mahesh 2012-07-18 15:14:41

+0

@Mahesh请解释“改为使用std :: string”。 std :: string不能解决问题,因为它也可能超出范围。解决方案的关键是使用分配的缓冲区/对象或静态对象,或让调用者提供自己的缓冲区。 – Les 2012-07-18 16:46:54

2

当get()函数返回时,局部变量超出范围。即,它的价值变得不明确。

来解决,可以使用...

static char ss[255]; 
// or 
char *ss = (char *)calloc(1,255); 
// or with C++ 
char *ss = new char[255]; 

或等等...

你决定取舍。使用静态变量,每次调用get()都可以更改缓冲区的内容。但通过涉及分配的方法,调用者需要释放内存并知道是使用free()还是delete。一些通过提供缓冲区时调用的功能等处理这个问题......

void get(char *buf, int limit); 
// or 
void get(char *buf, int& limitActual); 

然后最主要的是,与字符串处理时,在C/C++(甚至的std :: string)你正在处理内存必须以某种方式进行管理。使用字符串时,要非常小心自动变量。

+0

如果我做了“calloc”或“new char [255]”,那么我必须以某种方式在调用者端释放内存,否则当调用者超出范围时它将自动完成。 – vico 2012-07-19 14:30:43

+0

'ddd'dd ddd sadsadsadsadsa dsaasd – vico 2012-07-19 17:50:33

+0

纠正我,如果我错了。如果'void get(char * buf,int&limitActual);'调用者创建变量并设置它的长度。函数'get'填充缓冲区并将limitActual设置为填充信息长度。 ilimitActual总是> =比由调用者创建的缓冲区长度长。但是谁需要actualLength - 你总能看到零终止字符。 – vico 2012-07-19 17:56:34

2

你的数组ss []只存在于get()的范围内。
因此,您离开函数后,您从get()返回的指针无效。