Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;在作用域结束之前删除函数指针_C++_Scope_Function Pointers_Destructor - Fatal编程技术网

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_;
};