内存访问冲突错误 - 0xC0000005

时间:2010-06-12 08:56:35

标签: c++

我有时会遇到内存访问冲突错误....

但我不知道错误来自哪里......

所以我查看了代码,发现了一些奇怪的代码......

delete m_p1;
A *a = new A();
a->b = *c;
m_p1 = a; --> strange code.

我认为这有点奇怪......我可以在删除m_p1后使用m_p1吗?

它可以使一些内存访问错误??

5 个答案:

答案 0 :(得分:8)

调试内存访问冲突

你在Windows上。

这意味着如果在安装了Visual Studio的计算机上发生错误,您可以选择打开它来调试错误,从而知道发生错误的完全行。< / p>

学习代码

代码太少无法正确回答。人们可以猜测:

delete m_p1;

你确定m_p1是指向有效对象的指针吗? (分配有new等)

A *a = new A();

你必须检查A的构造函数。也许它做错了。

a->b = *c;

这是我怀疑的更多行:如果c是无效指针(NULL或指向某个随机地址),则取消引用它以将结果放入a->b可能会引发错误

m_p1 = a; --> strange code.

有趣的事实是,这是不能产生你得到的错误的唯一代码行:a是包含地址的指针,你可以复制地址。它正在使用此地址(取消引用指针等)导致内存访问冲突。

关于m_p1 = a;

这段代码并不那么奇怪,但它证明你仍然有指针问题。

在C,C ++,Java等中,当你分配一个内存(把东西放进去,创建一个对象等)时,分配器(new,malloc,等等......)会给你一个< EM>处理。在Java / C#中,这称为引用,在C / C ++中,这是一个指针。

让我们想象你会去参加一场音乐会,座位号就是你要坐的地方,而seat就是真实的物体,你会坐在那里并欣赏节目。

  • m_p1是您钱包里的一张纸,您想要准确的座位号
  • a是一张临时纸,一张餐巾纸,无论如何......
  • delete m_p1是您转售地点的时间,因此您之前购买的座位号码不再有效。你不应该再使用它了。
  • a = new A()是您购买另一个地方的时候,因此您在a另一个有效的座位号码,但无论出于何种原因,而不是写入您的钱包(m_p1),我会把它写在餐巾纸上。
  • m_p1 = a是指你最终将座位号码从一张餐巾纸复制到钱包里。

关键是你有:

  • 指针,包含内存地址(指针值)
  • 您拥有真实对象的内存地址

通过delete销毁一个真实对象不会破坏指针。它只会使地址无效(地址没有改变。它只是无效了)。所以你可以在指针中输入你想要的任何地址,甚至可以重用指针来包含另一个对象的地址。

答案 1 :(得分:4)

有什么奇怪的? m_p1是一个指针,有问题的行正在为它指定另一个指针。完全合法的C ++。代码不是C,所以我删除了那个标签。

答案 2 :(得分:1)

根据您所使用的平台,有一些工具可以帮助您找到这些问题。

首先,如果你遇到内存访问冲突问题,你应该能够获得类似核心文件的东西(至少在unix世界中,我确信它在Windows上被称为完全不同的东西)。 从那以后,您应该能够确切地看到违规发生的位置。

还有一些工具可以帮助您进行代码的静态分析和运行时检查内存违规。

coverity,purify和valgrind是一些想到的例子。

如果你在Windows上,这可能会有所帮助:how can I debug an access violation

答案 3 :(得分:1)

delete m_p1表示“m_p1指向过去用new分配的东西。请摆脱它”。 意味着“请摆脱指针m_p1”。

答案 4 :(得分:1)

抱歉复活了这个&#34;线程&#34;。

当我们尝试访问或删除已释放的内存时,通常会出现访问冲突。诀窍是;当您知道发生访问冲突的内存地址时,您可以创建数据断点并等待它被触发。在此之后,它会显示 where 此内存已被释放或修改。