让我们考虑以下示例,它引用了已经损坏的对象。
struct Config
{
unsigned int m_maxSize = 1;
};
class FileReader
{
public:
FileReader(Config& config) : m_cfg(config){
}
Config& m_cfg;
};
class FileReaderUser
{
FileReader* m_fileReader;
public:
FileReaderUser(){
Config cfg;
cfg.m_maxSize = 1234;
m_fileReader = new FileReader(cfg);
}
void PrintSize(){
std::cout << "Config value: " << m_fileReader->m_cfg.m_maxSize << std::endl;
}
};
int main()
{
FileReaderUser fileReaderUser;
fileReaderUser.PrintSize();
}
在此示例中,输出为0。我的问题是为什么它为零?如果其他对象已经占用了内存(不确定是否为真),或者没有修改过的旧值(1234),我希望发生访问冲突。它是在GCC 7.2.0的Debug中编译的。
答案 0 :(得分:4)
我的问题是为什么它为零?
因为该程序的行为是不确定的。这是程序可能具有的一种行为。
我希望
期望任何特殊行为都是愚蠢的。您的任何期望都不能保证是正确的。
如果其他对象已经占用了内存,则预期会发生访问冲突
操作系统检测到内存访问冲突。操作系统不了解C ++程序使用的“对象”,因此OS不知道是某个对象使用内存还是另一个对象使用。当您尝试访问具有无效映射的内存页面时,会遇到访问冲突。
更一般地说,如果您访问对象生命周期之外的语言,该语言不能保证您会遇到内存访问冲突。实际上,我认为在任何情况下C ++语言都不会提供这种保证。
或保持原价(1234)不变
不能保证在访问对象生命周期之外的值时都不会获得未更改的值。没有任何保证。