我有一个 C++ 类;这个类如下:

首先是标题:

class PageTableEntry {
public:

    PageTableEntry(bool modified = true);
    virtual ~PageTableEntry();

    bool modified();
    void setModified(bool modified);

private:
    PageTableEntry(PageTableEntry &existing);
    PageTableEntry &operator=(PageTableEntry &rhs);

    bool _modified;
};

和 .cpp 文件
#include "PageTableEntry.h"

PageTableEntry::PageTableEntry(bool modified) {
    _modified = modified;
}

PageTableEntry::~PageTableEntry() {}

bool PageTableEntry::modified() {
    return _modified;
}
void PageTableEntry::setModified(bool modified) {
    _modified = modified;
}

我在涉及 _modified 的 .cpp 文件中的所有 3 行上设置了一个断点,以便我可以准确地看到它们被设置/更改/读取的位置。顺序如下:
  • 构造函数中的断点被触发。 _modified 变量被确认设置为 true
  • 触发访问器中的断点。 _modified 变量是假的!

  • 这发生在每个 PageTableEntry 实例中。类本身并没有改变变量——别的东西是。不幸的是,我不知道是什么。该类是使用 new 动态创建的,并(作为指针)传递给各种 STL 结构,包括 vector 和映射。 mutator 从未被我自己的代码调用(我还没有达到那个点)并且 STL 结构不应该能够,并且由于从未在 mutator 上调用断点我只能假设它们不是.

    显然有一些“陷阱”,在某些情况下,私有(private)变量可以在不通过类的 mutator 的情况下更改,由谁知道是什么情况触发,但我无法想象它会是什么。有什么想法吗?

    更新:
    这在每个阶段的值(value):
    构造函数 1:0x100100210
    构造函数 2:0x100100400
    访问器 1:0x1001003f0
    访问器 2:0x100100440

    更新2:
    (代码显示访问 PageTableEntry 的位置)
    // In constructor:
        _tableEntries = std::map<unsigned int, PageTableEntry *>();
    
    // To get an entry in the table (body of testAddr() function, address is an unsigned int:
        std::map<unsigned int, PageTableEntry *>::iterator it;
        it = _tableEntries.find(address);
        if (it == _tableEntries.end()) {
            return NULL;
        }
        return (PageTableEntry *)&(*it);
    
    // To create a new entry:
        PageTableEntry *entry = testAddr(address);
        if (!entry) {
            entry = new PageTableEntry(_currentProcessID, 0, true, kStorageTypeDoesNotExist);
            _tableEntries.insert(std::pair<unsigned int, PageTableEntry *>(address, entry));
        }
    

    这些是 PageTableEntry 对象存储和从 STL 结构检索以导致问题的唯一点。所有其他函数都使用 testAddr() 函数来检索条目。

    无关:由于 C++ 现在有 65663 个问题,而今天到目前为止已经提出了 164 个问题,这意味着仅在今天,C++ 标记问题的数量超过了 16 位无符号整数。有用?不。有趣吗?是的。 :)

    最佳答案

    要么您的调试器未正确报告该值(并非闻所未闻,甚至在优化构建中预期),要么您的程序中的其他地方存在内存损坏。您显示的代码或多或少很好,应该按您的预期运行。

    编辑对应于您的“UPDATE2”:
    问题出在这一行:

    return (PageTableEntry *)&(*it);
    
    *it 的类型是 std::pair<unsigned const, PageTableEntry*>& ,因此您可以有效地将 std::pair<unsigned const, PageTableEntry*>* 重新解释为 PageTableEntry* 。将该行更改为:
    return it->second;
    

    注意代码库中的其他类型转换。首先需要强制转换是一种代码异味,错误执行强制转换的结果可能是未定义的行为,包括表现为您在此处看到的内存损坏。使用 C++ 风格的强制转换而不是 C 风格的强制转换可以很容易地找到代码库中发生强制转换的位置,以便可以轻松地查看它们( 提示、提示 )。

    关于C++ bool 变量变化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5624788/

    10-08 22:02