【问题标题】:Exception thrown at 0x7A2A93B6 (vcruntime140d.dll) in file.exe: 0xC0000005: Access violation reading location 0xCDCDCDCD在 file.exe 中的 0x7A2A93B6 (vcruntime140d.dll) 处引发异常:0xC0000005:访问冲突读取位置 0xCDCDCDCD
【发布时间】:2021-07-03 23:18:20
【问题描述】:

我在尝试获取数组的 typeid 时遇到问题。当我输入 typeid(*ptr[0]).name() 时,它工作得非常好。但是一旦我将 0 更改为循环中的变量,它就会给我这个错误,请帮助我!

#include "Cellphone.h"
#include "Electronic_device.h"
#include "Laptop.h"
#include "Smartwatch.h"
#include <vector>
#include <typeinfo>

int main()
{
    string name;
    int i = 0;
    Electronic_device** ptr = new Electronic_device*[100];
    Cellphone c1("Samsung", 1023, "black", 250.00, 1);
    Smartwatch s1("IBM", 10, "red", 350.00, 2);
    Laptop l1("HP", 102, "black", 1250.00, 16, true);
    ptr[0] = &c1;
    ptr[1] = &s1;
    ptr[2] = &l1;
    ptr[0]->print();
    
    for (i = 0; i < sizeof(ptr); i++)
    {
        if (typeid(*ptr[i]) == typeid(Cellphone))
        {
            cout << "Cellphone" << endl;
        }
        if (typeid(*ptr[i]) == typeid(Smartwatch))
        {
            cout << "Smartwatch" << endl;
        }
        if (typeid(*ptr[i]) == typeid(Laptop))
        {
            cout << "Laptop" << endl;
        }
    }
    
    ((Cellphone *)ptr[0])->printCellphone();
}

【问题讨论】:

  • 0xCDCDCDCD 我们常用的memory bit pattern 用于未初始化的堆分配内存。
  • sizeof(ptr) 将是 4 或 8,即 32 或 64 位,而不是 100。在两个位置使用相同的常量。
  • 关于您的问题的一个重要提示:sizeof(ptr)指针 ptr 的大小(以 字节 为单位),而不是数量它可能指向的任何可能数组的元素。并不是说即使是这样也可以,因为您没有初始化数组的所有元素。请改用std::vector&lt;Electronic_device*&gt;!而且typeid(*ptr[i]) == typeid(Cellphone)不行,最好改用多态和虚函数。
  • sizeof(ptr) 不会告诉你数组有多大,它会告诉你指针的大小(以字节为单位)
  • 一般来说,当您看到一个非常重复的数字或看起来有点像单词或短语的数字时,很有可能程序试图告诉您一些事情,您应该查找该数字。当你得到一个奇怪的十进制数字时,把它变成十六进制,看看它是否更容易识别/重复。

标签: c++


【解决方案1】:

您正在读取未初始化的内存。首先,将你的数组初始化为零,这样所有的指针都是空的:

Electronic_device** ptr = new Electronic_device*[100]();

其次,在取消引用指针(调用*ptr[i])之前,必须检查值不为空,例如:

for (i = 0; i < 100 && ptr[i] != nullptr; i++)

如果您使用dynamic_cast 来检查派生类,那么您根本不必在示例中取消引用指针:

if (dynamic_cast<Cellphone*>(ptr[i]) != nullptr) {
    cout << "Cellphone" << endl;
}

【讨论】:

  • 他的数组不包含 nullptr,因为他从不分配它。为了使您的解决方案起作用,他也会执行 ptr[3] = nullptr 。
  • @AndersK 这就是我指示将数组初始化为零的原因。零等于 nullptr。见stackoverflow.com/questions/7546620/…
  • 我想我没有看到,我主要看代码并掩盖文本 :) 可能是坏习惯,但我认为这会让你的答案更清楚。
  • 非常感谢!通过将 () 添加到我的数组初始化并将 ptr[i] != nullptr 添加到我的 for 循环中,它停止了内存泄漏并能够完成我的分配。
猜你喜欢
  • 2020-08-09
  • 2020-02-13
  • 2018-06-26
  • 2016-07-14
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
相关资源
最近更新 更多