【问题标题】:0xC0000005: Access violation reading location 0x00000000000000080xC0000005:访问冲突读取位置0x0000000000000008
【发布时间】:2018-06-08 06:55:16
【问题描述】:

我正在尝试制作一个使用从三个不同数组访问的预设音节的名称生成器。

#include "main.hpp"

Namegen::Namegen() {
}

const char *Namegen::getFirst() {
    const char *name;
    int rNum = rng->getInt(0, 5);
    const char *firstSyllable = start[rNum];
    rNum = rng->getInt(0, 5);
    const char *secondSyllable = mid[rNum];
    rNum = rng->getInt(0, 5);
    const char *lastSyllable = end[rNum];

    name = firstSyllable + *secondSyllable + *lastSyllable;

    return name;
}

每个数组共有 6 个音节,所以我将最小值设置为 0,最大值设置为 5。总共六个数字。然而,出于某种原因,它看起来像是在某个地方生成了 8?我不完全确定异常在说什么,但希望其他人能做到。这是一个例外(即使它已经在标题中):

0xC0000005: Access violation reading location 0x0000000000000008.

这是我的 Namegen.hpp 文件(通过 main.hpp 文件链接):

#pragma once

class Namegen {
public:
    const char *start[6] = { "Ba", "Ce", "Ti", "Mo", "Lu", "Dy" };
    const char *mid[6] = { "ma", "te", "di", "so", "ku", "ly" };
    const char *end[6] = { "ban", "can", "dan", "fan", "gan", "han" };

    Namegen();
    TCODRandom *rng;
    const char *getFirst();
};

为什么会抛出这个异常,我该如何解决?

我可以使用以下代码成功连接这些值:

std::string Namegen::getName() {
    int r = rng->getInt(0, 2);
    std::string firstSyll = fSyll[r];
    r = rng->getInt(0, 2);
    std::string midSyll = mSyll[r];
    r = rng->getInt(0, 2);
    std::string lastSyll = lSyll[r];

    std::string name = std::string(firstSyll) + std::string(midSyll) + std::string(lastSyll);

    return name;
}

然而,它现在抛出这个异常:

Exception thrown at 0x00007FF978AD9E7A (ucrtbased.dll) in AotDK.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

【问题讨论】:

  • 您不能为const 变量赋值。你只能初始化它们(我有点惊讶它编译)。由于您没有初始化name,因此它是一些随机的垃圾指针。然后,您尝试写入该位置,即未定义行为。
  • 你希望name = firstSyllable + *secondSyllable + *lastSyllable; 做什么?
  • 您或许可以考虑使用std::string 和诸如std::vector 之类的STL 容器。另外,请查看您如何连接名称部分。
  • @Yksisarvinen 不,OP 不会尝试写入 name 指向的位置。他分配了所述内存位置,而不取消引用它。
  • @JacobMcNamara 那么,你应该向good C++ book 学习 C++。通过猜测来学习 C++不是正确的方法。

标签: c++ exception


【解决方案1】:

name = firstSyllable + *secondSyllable + *lastSyllable; 不是接近的串联。 (编译器编译它,因为它认为您正在对firstSyllable 进行一些指针运算。)行为实际上是未定义的,因为您将不是nullptr 或对象地址分配给name

抛弃所有char* 的东西,改用std::string。然后+ 充当连接,因为它是字符串类中的重载运算符。

您的数据将采用以下形式

std::vector<std::string> start = { "Ba", "Ce", "Ti", "Mo", "Lu", "Dy" };

展示了 C++ 标准库的强大功能。您需要 #include &lt;string&gt;#include &lt;vector&gt; 才能引入该功能。

【讨论】:

  • 我得到以下信息:命名空间“std”没有成员“字符串”。
  • @JacobMcNamara #include &lt;string&gt;?
  • @JacobMcNamara:请参阅下一条评论和对答案的修改。顺便说一句,C++ 的学习曲线并不浅!真的,你需要一本好书。到目前为止,Stroustrup 是我最喜欢的。我会留出三个月的时间先阅读 K&R;完成所有示例练习。
  • 您可以使用 std::string 进行所有字符串操作,然后在需要(只读)访问字符缓冲区时调用 c_str() 方法。
  • @JacobMcNamara:这取决于您尝试调用的期望const char* 的函数是什么。现在真的是你放下工具开始​​阅读的时候了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-06
相关资源
最近更新 更多