访问违规写入位置0xcccccccc。

10

在过去的两天中,我被卡在了一个违规问题上,但我似乎无法解决它。

我已经使用断点定位了错误所在的位置,但我希望你们中的一位能够知道问题所在,而无需我将所有代码都复制粘贴 -.-

我收到以下信息:

 
   

在 Escape.exe 中,0x1027cb1a(msvcr100d.dll)发生了第一次机会异常:访问位置 0xcccccccc 时访问冲突。 在 Escape.exe 中,0x1027cb1a(msvcr100d.dll)未处理的异常:0xC0000005:访问位置 0xcccccccc 时访问冲突。

 

现在,快速的谷歌搜索让我认为有些奇怪的事情正在发生。所有的搜索结果都谈论指针实际上没有指向任何地方(0xccccccccc是低内存地址?)。

虽然我还没有在我的代码中使用指针,但无论如何我都会复制这个函数并指出引发异常的那一行(用粗体标记):

void mMap::fillMap(){
    for(int i = 0; i <= 9; i++){
        for(int z = 0; z <= 19; z++){
            Tile t1;    // default Tile Type = "NULLTILE"
            myMap[i][z] = t1;
        }
    }
}

现在myMap是一个类型为Tile的二维数组。我几天前还可以运行,但我添加了其他类后就无法工作了!


那么,如果你注释掉代码的这一部分,它就可以正常工作了? - soandos
我的 myMap 在哪里被初始化了? - Etienne de Martel
myMap在mMap.h中。Tile myMap[10][20]; - Linky
4个回答

11

可能是未初始化的指针,或者指向已经被释放的内存。我认为cccccccc是前者,cdcdcdcd是后者,但是这取决于编译器/库的实现。

对于你的特定代码,可能是因为myMap尚未分配空间,那么myMap[0][0]将会试图访问0xcccccccc


可能还会发生myMap是你的类的开头,并且类指针未初始化的情况:

class mMap
{
     Tile myMap[10][20];
public:
     void f() { myMap[0][0] = 0; }
};

mMap* what;
what->f(); // what is an invalid pointer
这是因为成员函数不是虚函数,所以编译器知道要运行哪段代码,并将对象指针作为隐藏参数传递。最终,编译器会发出类似以下的计算:
this + offsetof(Whatever::myMap) + z * sizeof(myMap[0]) + i * sizeof(myMap[0][0])

this尚未初始化,因此为0xcccccccc。显然,offsetof部分为零,且在循环的第一次中,iz都为零,因此您得到0xcccccccc + 0 + 0 + 0作为内存地址。


要调试此问题,请使用调用堆栈并找到调用fillMap的函数。然后检查该函数中用于成员访问(->)的指针来自哪里。


@Linky:请看我的编辑。这个地址几乎总是由于指针未设置而引起的,在你的情况下,myMap 不是一个指针,所以它必须是包含 myMap 的类的指针有问题。 - Ben Voigt
@Linky:我理解。这就是我回答的第二部分和第三部分所讨论的情况。 - Ben Voigt
我正在使用驱动程序类测试这些类。如果我输入:mMap mappy;通过调用mMap类的构造函数,它会调用fillMap(),这就是错误发生的地方。myMap数组是局部的,这就是为什么抛出指针相关错误让我感到困惑的原因。 - Linky
所以我猜它是想告诉我我的myMap[10][20]数组未初始化。但是我在头文件中已经声明了,不理解为什么会这样!!顺便感谢大家的帮助 :) - Linky
@Linky:被声明和被初始化是两件不同的事情。 - sean e
显示剩余7条评论

4

在MSVC++和调试模式下,调试内存分配器将所有返回的内存设置为0xcccccccc,以便找到未定义行为的情况。很可能您从未初始化myMap,或者myMap中的某些指针。检查您的初始化代码是否存在错误。


请展示如何正确地初始化 Tile myMap [10][20];。 - Linky
2
当使用/GZ时,会出现0xcccccccc。https://dev59.com/ZXRC5IYBdhLWcg3wOeWB - sean e

1
当我尝试使用for循环填充自己类类型的表元素时,遇到了类似的错误。我在那个表中声明了1000个元素,所以我放置了类似于以下内容的东西:
    for (int i = 0; i <= 1000; i++)
    {
        TAble[i].name = "Some Guy";
        TAble[i].age = 4;
    }

不幸的是,就像字符串一样,我可能在坚持填充不存在的元素,即表格中的第1000个元素。通过更改循环头部并删除1000前面的等号,我成功解决了这个问题。

请尝试查看您是否正在尝试调用不存在的内容。


1
已经过去三年了,但也许这会帮助其他遇到类似问题的人。 :) 干杯! - Russia Must Remove Putin

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接