2011-02-14 70 views
2

我不是C++开发人员,我试图弄清楚为什么当我从一个函数返回一个C字符串时,我得到了垃圾。在C++中传递C-Strings的问题

#include <stdio.h> 

const char* tinker(const char* foo); 

int main(void) 
{ 
    const char* foo = "foo"; 
    foo= tinker(foo); 
    printf(foo); // Prints garbage 
    return 0; 
} 

const char* tinker(const char* foo) 
{ 
    std::string bar(foo); 
    printf(bar.c_str()); // Prints correctly 
    return bar.c_str(); 
} 
+1

inside tinker try std :: string bar = new std :: string(foo); – 2011-02-14 17:42:02

+2

@jason首先,它会是`std :: string * bar = new std :: string(foo);`第二,这将是内存泄漏,因为没有人释放动态分配的字符串对象。 – HighCommander4 2011-02-14 17:46:55

回答

2

要添加什么其他人说,这是为了得到它的工作的一种方法:

#include <stdio.h> 

std::string tinker(const char* foo); 
int main(void) 
{ 
    const char* foo = "foo"; 
    std::string foo2= tinker(foo); 
    printf(foo2.c_str()); // Prints correctly 
    return 0; 
} 

std::string tinker(const char* foo) 
{  
    std::string bar(foo); 
    return bar; 
} 

这里的std :: string对象被复制*通过返回值和要打印的副本主()。

*流行的字符串实现采用引用计数等避免实际复制字符串的优化。另外,在C++ 0x中,字符串对象将被移动,而不是被复制。

8

您正在返回基于std::string的内部存储器的C字符串。但是,在您的bar遭到破坏之后正在打印此文件。这个内存在到达printf(foo);的时候是垃圾。

+0

很好的解释,谢谢! – 2011-02-14 17:55:41

1

因为你在修补程序的堆栈中分配条。当修补程序结束时,它的栈被回收,bar被删除,所以你返回的指针指向释放内存,也就是说,当你退出函数时它不再有效。

4

您正在返回指向bar内部缓冲区的指针,但是在使用该指针之前,您将销毁bar(和缓冲区)。

如果在函数返回后需要bar的内容,则返回bar而不是bar.c_str()

1
return bar.c_str(); 

此行返回一个临时对象,它被在该函数的端缺失的char*,因此,在主()foo指向已删除对象char*

1

因为酒吧住在修补匠的堆栈上;离开函数后,其c_str()消失。