Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.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++_Scope - Fatal编程技术网

C++ 跟踪自动变量寿命?

C++ 跟踪自动变量寿命?,c++,scope,C++,Scope,这可能不可能,但我想我会问 有没有什么方法可以让任何人在不修改变量本身的类的情况下跟踪自动变量是否已被删除?例如,考虑这个代码: const char* pStringBuffer; { std::string sString( "foo" ); pStringBuffer = sString.c_str(); } 显然,在块之后,pStringBuffer是一个悬空指针,它可能有效,也可能无效。我想要的是一个包装类,它包含pStringBuffer(带有constchar*的

这可能不可能,但我想我会问

有没有什么方法可以让任何人在不修改变量本身的类的情况下跟踪自动变量是否已被删除?例如,考虑这个代码:

const char* pStringBuffer;
{
    std::string sString( "foo" );
    pStringBuffer = sString.c_str();
}
显然,在块之后,pStringBuffer是一个悬空指针,它可能有效,也可能无效。我想要的是一个包装类,它包含pStringBuffer(带有constchar*的casting操作符),但是声明它引用的变量仍然有效。通过更改引用变量的类型,我当然可以做到这一点(例如,boost shared_ptr/weak_ptr),但我希望能够做到这一点,而不必对引用类型施加限制

一些想法:

  • 我可能需要更改赋值语法以包含引用的变量(这很好)
  • 我可能可以通过查看堆栈指针来检测我的包装器类是否比引用的类分配得“晚”,但这似乎是不规范的,也不是标准的(C++没有定义堆栈行为)。不过,这可能会奏效

想法/卓越的解决方案?

您可能会发现一种有用的技术是用自己的实现替换
新的
/
删除
操作符,该实现将使用的内存页(由
操作符新的
分配)在释放时标记为不可访问(由
操作符删除
解除分配)。您将需要确保永远不会重复使用内存页,但是,由于内存耗尽,运行时长度会受到限制

如果应用程序在释放内存页后访问它们,如上面的示例所示,操作系统将捕获尝试的访问并引发错误。它本身并不是精确的跟踪,因为应用程序将立即停止,但它确实提供了反馈:-)


这种技术适用于狭窄的场景,不会捕获所有类型的内存滥用,但它可能很有用。希望能有所帮助。

您可能会发现一种有用的技术是用自己的实现替换
新的
/
删除
操作符,该实现将使用的内存页(由
操作符新的
分配)在释放时标记为不可访问(由
操作符删除
解除分配)。您将需要确保永远不会重复使用内存页,但是,由于内存耗尽,运行时长度会受到限制

如果应用程序在释放内存页后访问它们,如上面的示例所示,操作系统将捕获尝试的访问并引发错误。它本身并不是精确的跟踪,因为应用程序将立即停止,但它确实提供了反馈:-)


这种技术适用于狭窄的场景,不会捕获所有类型的内存滥用,但它可能很有用。希望有帮助。

一般来说,因为指针太“原始”,所以C++里面是不可能的。另外,查看是否分配的时间晚于引用的类也不起作用,因为如果更改字符串,那么c_str指针很可能会更改

在这种特殊情况下,您可以检查字符串是否仍然返回与c_str相同的值。如果是,则可能仍然有效,如果不是,则指针无效


作为一个调试工具,我建议使用高级内存跟踪系统,如valgrind(恐怕只适用于linux。windows上也有类似的程序,但我相信它们都是花钱的。这个程序是我在mac上安装linux的唯一原因)。valgrind以程序执行速度慢得多为代价,检测您是否读取过无效指针。虽然它不是完美的,但我发现它检测到许多错误,特别是这种错误。

一般来说,它是不可能的C++内,因为指针太“原始”。另外,查看是否分配的时间晚于引用的类也不起作用,因为如果更改字符串,那么c_str指针很可能会更改

在这种特殊情况下,您可以检查字符串是否仍然返回与c_str相同的值。如果是,则可能仍然有效,如果不是,则指针无效


作为一个调试工具,我建议使用高级内存跟踪系统,如valgrind(恐怕只适用于linux。windows上也有类似的程序,但我相信它们都是花钱的。这个程序是我在mac上安装linux的唯一原因)。valgrind以程序执行速度慢得多为代价,检测您是否读取过无效指针。虽然它并不完美,但我发现它检测到许多bug,特别是这种类型的bug。

您可以创建一个包装器类,它可以在您提到的简单情况下工作。也许是这样的:

X<const char*> pStringBuffer;
{
    std::string sString( "foo" );
    Trick trick(pStringBuffer).set(sString.c_str());
} // trick goes out of scope; its destructor marks pStringBuffer as invalid
xpstringbuffer;
{
std::字符串sString(“foo”);
技巧技巧(pStringBuffer).set(sString.c_str());
}//技巧超出范围;它的析构函数将pStringBuffer标记为无效
但这无助于更复杂的情况:

X<const char*> pStringBuffer;
{
    std::string sString( "foo" );
    {
        Trick trick(pStringBuffer).set(sString.c_str());
    } // trick goes out of scope; its destructor marks pStringBuffer as invalid
}
xpstringbuffer;
{
std::字符串sString(“foo”);
{
技巧技巧(pStringBuffer).set(sString.c_str());
}//技巧超出范围;其析构函数将pStringBuffer标记为无效
}
在这里,失效发生得太快了


大多数情况下,您应该只编写尽可能安全的代码(请参阅:智能指针),但不应该编写更安全的代码(请参阅:性能,低级接口),并使用工具(valgrind,Purify)确保没有任何漏洞。

您可以创建一个包装器类,在您提到的简单情况下工作。也许是这样的:

X<const char*> pStringBuffer;
{
    std::string sString( "foo" );
    Trick trick(pStringBuffer).set(sString.c_str());
} // trick goes out of scope; its destructor marks pStringBuffer as invalid
xpstringbuffer;
{
std::字符串sString(“foo”);
技巧技巧(pStringBuffer).set(sString.c_str());
}//技巧超出范围;它的析构函数将pStringBuffer标记为无效
但这无助于更复杂的情况:

X<const char*> pStringBuffer;
{
    std::string sString( "foo" );
    {
        Trick trick(pStringBuffer).set(sString.c_str());
    } // trick goes out of scope; its destructor marks pStringBuffer as invalid
}
xpstringbuffer;