取消引用指向类成员的指针时发生 C++ 访问冲突

标签 c++ access-violation dereference

在我的程序中,我试图取消引用指向结构文章的指针,以获取其 ID,但我得到“访问冲突读取位置 0xCCCCCCCC”。我尝试了很多不同的东西,局部变量,将指针回溯到代码中,不同的括号……什么都没有。我别无选择,无论我怎么努力都看不到问题。

这个问题可能有答案,但访问冲突太笼统了,我无法找到我正在寻找的答案(而且大多数问题都围绕数组,这不是我的情况) .

我在这里定义了一个简单的结构来保存我的数据。

struct Article {
public:
    std::string id;
    std::string title;
    std::string text;
    Article(std::string article_id, std::string article_title, std::string article_text) : id(article_id), title(article_title), text(article_text) {};
    void toString();
};

接下来,我使用字典将所有单词映射到它们出现的文章。代码本身并没有完成,但是单词映射应该包括所有必要的指针。

std::map<std::string, std::map<Article*, unsigned>> word_dict_;

我还保留了另一个 vector<Article> articles_我保留所有这些的地方,因此 word_dict_ 中不应出现空指针;

字典在这里生成。

void fulltext::generateDict() {
    for (Article ar : articles_) {
        unsigned wordStart;
        bool isBuilding = false;
        string buffer = "";
        for (unsigned int it = 0; it <= ar.text.size(); ++it) {
            char c;
            if (it < ar.text.size())
                c = ar.text.at(it);
            else
                c = '\0';

            if (isalpha(c)) {
                // start or middle of word
                if (!isBuilding) {
                    isBuilding = true;
                    wordStart = it;
                }
                buffer += c;
            }
            else {
                isBuilding = false;
                if (buffer != "") {
                    stringToLower(buffer); // rewrites buffer to low case
                    // Here I tried creating &ar just for the laughs and it works just fine.
                    word_dict_[buffer][&ar] = wordStart;
                    buffer = "";
                }
            }
        }
    }
}

最后但同样重要的是,我想打印出来,真正的乐趣就在这里开始。

void fulltext::printWordDict() {

    cout << "Printing generated word dictionary: " << endl;

    for (auto wordPair : word_dict_) {
        cout << " \" " << wordPair.first << " \" " << endl;
        cout << "There are " << wordPair.second.size() << " inputs." << endl;
        for (pair<Article*, unsigned int> articlePair : wordPair.second) {
            cout << (articlePair.first)->id << endl; // Here the access violation occurs
            // Nothing seemingly works
            // cout << articlePair.first->id; ... Access violation
            // cout << (*articlePair.first).id; ... Access violation
            // auto ar = articlePair.first; cout << ar->id; ... access violation
            // auto ar = articlePair.first; cout << (*ar).id; ... access again
        }
        cout << endl;
    }
    cout << "Done." << endl;
}

这些函数是从主函数中调用的 fulltext::proccess()巧合的是紧接而来。 word_dict_ 是类私有(private)变量。

如果需要代码的任何其他部分,请告诉我,尽管在这种情况下其他部分都不会产生任何问题。

最佳答案

for (Article ar : articles_) {
     ...
    word_dict_[buffer][&ar] = wordStart;
    ...
}

在这里,您在字典中存储了一个指向 ar 的指针,但是 ar 在其范围的末尾被销毁 - 当您的 for 循环结束时。所以现在您在 map 中存储了一个悬空指针,您无法取消引用它。

在您的 map 中存储 Article 对象而不是 Article* ,或者以其他方式确保 Article 对象存在于某个地方,只要您有一个指针在你的 map 上。

如果您的 articles_ 容器中存在对象,您可能不需要将其复制到 for 循环中,而是执行以下操作:

for (Article& ar : articles_) {
   .. 
   word_dict_[buffer][&ar] = wordStart;

现在您将获得一个指向位于 article_ 中的 Article 对象的指针。

虽然稍后要注意您对 article_ 做了什么 - 如果您对它执行移动对象的操作(这可能由于多种原因发生,具体取决于容器类型),您在 中的指针>word_dict_ 变得无效。

关于取消引用指向类成员的指针时发生 C++ 访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53521812/

相关文章:

c++ - 使用 ASSIMP 和 GLSL 的骨骼动画 : bone uniform array size

c# - 可以信任 AccessViolationException 的 Stacktrace

c - 如何修复非结构或 union 中的 "request for member ‘rank’”?

c++ - 为什么 `T* operator->()`写了一次就重复申请了?

c++ - 使用 C++ 代码从 C 代码回调?

c++ - 当前草案中 [expr.ref]/(4.2) 和 [expr.sub]/1 之间是否存在矛盾?

c++ - Boost 错误代码引用

c++ - CString 内的内存访问冲突

c++ - mlock 中的访问冲突

C编程: Dereferencing pointer to incomplete type error