3

我有一个 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;
}

我在 .cpp 文件中涉及 _modified 的所有 3 行上设置了一个断点,这样我就可以准确地看到它们被设置/更改/读取的位置。顺序如下:

  1. 构造函数中的断点被触发。_modified 变量确认设置为true
  2. 访问器中的断点被触发。_modified 变量为假!

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

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

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

UPDATE2:(
显示访问 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 位无符号整数。有用?不,有趣吗?是的。:)

4

5 回答 5

9

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


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

return (PageTableEntry *)&(*it);

的类型*itstd::pair<unsigned const, PageTableEntry*>&,因此您有效地将 a 重新解释std::pair<unsigned const, PageTableEntry*>*为 a PageTableEntry*。将该行更改为:

return it->second;

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

于 2011-04-11T17:02:45.047 回答
4

std::map<>::find()返回 aniterator取消引用时返回 a std::map<>::value_type。在value_type这种情况下是一个std::pair<>. 您正在返回该地址pair而不是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 (*it).second;

PS:C 风格的演员表是邪恶的。编译器会发出带有 C++ 类型转换的诊断。:)

于 2011-04-11T18:05:49.930 回答
3

尝试查看this每个断点处的值。

于 2011-04-11T17:01:42.910 回答
0

如果您使用的是 STL 容器,那么复制构造函数和赋值运算符都会被大量使用。也许如果您向我们展示这些代码,我们会发现有问题。

于 2011-04-11T17:04:23.300 回答
0

您可以向该类添加另一个唯一值以跟踪 PageTableEntry 吗?我知道我遇到过这样的问题,真正的问题是有多个条目看起来相同,并且断点可能会在我没有意识到的情况下切换 PageTableEntry 。

于 2011-04-11T17:44:07.617 回答