C++ C++;在作用域结束之前删除函数指针
如果我有一个函数:C++ C++;在作用域结束之前删除函数指针,c++,scope,function-pointers,destructor,C++,Scope,Function Pointers,Destructor,如果我有一个函数: std::string returnString() { return "Hello, World!"; } 电话: std::string hello = returnString(); std::cout << hello << std::endl; 并尝试使用以下工具打印: for (const char* p = hello; *p; ++p ) { std::cout << *p; } std::cout &l
std::string returnString() {
return "Hello, World!";
}
电话:
std::string hello = returnString();
std::cout << hello << std::endl;
并尝试使用以下工具打印:
for (const char* p = hello; *p; ++p ) {
std::cout << *p;
}
std::cout << std::endl;
for(const char*p=hello;*p;++p){
std::cout(注意:我在这里忽略了一些细节。如果您想知道我在这里提到的规则的例外情况,请查找返回值优化和复制省略。不过,不会改变我在这个答案中描述的行为)
从函数返回对象时,返回的对象将在调用该函数的行的末尾被销毁。通常情况下都是这样。通常,您会将该对象复制或移动到本地范围内的另一个对象中,如上一个代码段中所示:
std::string hello = returnString();
在这一行中,returnString
返回一个std::string
对象,hello
是从返回的对象构造的,然后原始对象被销毁
如果你考虑一条稍微不同的线,那就是问题出现的时候:
const char* hello = returnString().c_str();
在这种情况下,returnString
返回一个std::string
对象,您保存一个指向该std::string
对象所拥有的char
数组的指针,然后原始std::string
对象被销毁,其中包含一个指针指向的char
数组
std::string
保留由c_str
返回的指针指向的char
数组的所有权。std::string
在超出范围时删除其拥有的数组,这意味着所指数组的生存期与std::string
对象的生存期相关联
您可以将std::string
想象成这样:
class string
{
public:
string(const char* str)
: ptr_(new char[strlen(str) + 1])
{
strcpy(ptr_, str);
}
~string()
{
delete[] ptr_;
}
const char* c_str()
{
return ptr_;
}
// other members
private:
const char* ptr_;
};
真正的std::string
有点复杂,但基本思想是一样的。当构建std::string
对象时,它分配一个char
s数组来保存字符串数据,当std::string
对象被销毁时,它会删除该数组
c_str
方法只返回一个指向std::string
内部char
数组的指针。仅仅因为你有一个指向该数组的指针并不意味着当std::string
对象死亡时它不会被删除,它只意味着你有一个指向不再拥有的内存的指针。这个问题怎么样关于OpenGL?“const char*vertSource=read_文件(m_FragPath)之间的区别”区别在于它无效?编辑了标记和问题,但它的意思是const char*vertSource=read_文件(m_FragPath).c_str()除了C++之外,一个换行符就像其他空白一样。预处理程序只关心行,没有别的。特别是,谈论行可能导致代码误码,比如<代码>(conchchar p= f-),cxStRew(;
p
的所有用法都与临时的std::string
在同一行,甚至是同一for
语句的一部分。而且它仍然是UB,因为存在一个终生的问题。@BenVoigt虽然使用“statement”而不是“line”更正确,但我觉得解释会使答案复杂化“什么是陈述?”只会分散我试图解释的核心概念的注意力。因此我选择使用口语“行”"为了保持简单。感谢您的详细解释。为了简化,如果函数完全绕过std::string
,并返回一个C字符串,那么引用不会被删除?@jackw11111:如果它返回一个C字符串,它将不会被自动释放——永远不会。如果C字符串具有静态存储持续时间,例如stri,这不是问题ng literal。如果它是动态数据,可能来自文件,则可能会出现内存泄漏。@MilesBudnek@BenVoigt好的。因此,由于对象被销毁时发生的delete ptr\ucode>或std::string
析构函数中的等效调用,数组被删除。string hello=returnString()
line,因为它在删除之前复制了对象。再次感谢。
class string
{
public:
string(const char* str)
: ptr_(new char[strlen(str) + 1])
{
strcpy(ptr_, str);
}
~string()
{
delete[] ptr_;
}
const char* c_str()
{
return ptr_;
}
// other members
private:
const char* ptr_;
};