C++ 解决错误的一般方法:围绕变量“x”的堆栈已损坏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13142419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:01:20  来源:igfitidea点击:

General way of solving Error: Stack around the variable 'x' was corrupted

c++visual-studio-2010debugging

提问by lezebulon

I have a program which prompts me the error in VS2010, in debug :

我有一个程序在调试中提示我 VS2010 中的错误:

Error: Stack around the variable 'x' was corrupted

This gives me the function where a stack overflow likely occurs, but I can't visually see where the problem is.

这为我提供了可能发生堆栈溢出的函数,但我无法直观地看到问题出在哪里。

Is there a general way to debug this error with VS2010? Would it be possible to indentify which write operation is overwritting the incorrect stack memory? thanks

有没有通用的方法可以用 VS2010 调试这个错误?是否可以确定哪个写操作覆盖了不正确的堆栈内存?谢谢

采纳答案by David Hammen

Is there a general way to debug this error with VS2010?

有没有通用的方法可以用 VS2010 调试这个错误?

No, there isn't. What you have done is to somehow invoke undefined behavior. The reason these behaviors are undefined is that the general case is very hard to detect/diagnose. Sometimes it is provably impossible to do so.

不,没有。你所做的是以某种方式调用未定义的行为。这些行为未定义的原因是一般情况很难检测/诊断。有时,事实证明这样做是不可能的。

There are however, a somewhat smallish number of things that typically cause your problem:

但是,通常会导致您出现问题的情况很少:

  • Improper handling of memory:
    • Deleting something twice,
    • Using the wrong type of deletion (freefor something allocated with new, etc.),
    • Accessing something after it's memory has been deleted.
  • Returning a pointer or reference to a local.
  • Reading or writing past the end of an array.
  • 内存处理不当:
    • 删除东西两次,
    • 使用错误的删除类型(free用于分配的内容new等),
    • 在删除内存后访问某些内容。
  • 返回指向本地的指针或引用。
  • 读取或写入数组末尾。

回答by Luchian Grigore

This can be caused by several issues, that are generally hard to see:

这可能是由几个通常很难看到的问题引起的:

  • double deletes
  • deletea variable allocated with new[]or delete[]a variable allocated with new
  • deletesomething allocated with malloc
  • deletean automatic storage variable
  • returning a local by reference
  • 双重删除
  • delete分配的变量new[]delete[]分配的变量new
  • delete分配的东西 malloc
  • delete自动存储变量
  • 通过引用返回本地

If it's not immediately clear, I'd get my hands on a memory debugger (I can think of Rational Purify for windows).

如果不是很清楚,我会使用内存调试器(我可以想到适用于 Windows 的 Rational Purify)。

回答by Omaha

This message can also be due to an array bounds violation. Make sure that your function (and every function it calls, especially member functions for stack-based objects) is obeying the bounds of any arrays that may be used.

此消息也可能是由于违反数组边界造成的。确保您的函数(以及它调用的每个函数,尤其是基于堆栈的对象的成员函数)遵守可能使用的任何数组的边界。

回答by marcinj

Actually what you see is quite informative, you should check in near x variable location for any activity that might cause this error.

实际上,您所看到的信息非常丰富,您应该检查靠近 x 变量位置的任何可能导致此错误的活动。

Below is how you can reproduce such exception:

以下是如何重现此类异常:

int main() {
    char buffer1[10];
    char buffer2[20];
    memset(buffer1, 0, sizeof(buffer1) + 1);
    return 0;
}

will generate (VS2010):

将生成(VS2010):

Run-Time Check Failure #2 - Stack around the variable 'buffer1' was corrupted.

运行时检查失败 #2 - 变量“buffer1”周围的堆栈已损坏。

obviously memset has written 1 char more than it should. VS with option \GS allows to detect such buffer overflows (which you have enabled), for more on that read here: http://msdn.microsoft.com/en-us/library/Aa290051.

显然 memset 比它应该多写了 1 个字符。带有选项 \GS 的 VS 允许检测此类缓冲区溢出(您已启用),有关此处阅读的更多信息:http: //msdn.microsoft.com/en-us/library/Aa290051

You can for example use debuger and step throught you code, each time watch at contents of your variable, how they change. You can also try luck with data breakpoints, you set breakpoint when some memory location changes and debugger stops at that moment,possibly showing you callstack where problem is located. But this actually might not work with \GS flag.

例如,您可以使用调试器并逐步执行代码,每次查看变量的内容,它们如何变化。你也可以试试数据断点的运气,当一些内存位置发生变化时设置断点并且调试器在那一刻停止,可能会向你显示问题所在的调用堆栈。但这实际上可能不适用于 \GS 标志。

For detecting heap overflows you can use gflags tool.

为了检测堆溢出,您可以使用 gflags 工具。

回答by Calmarius

I was puzzled by this error for hours, I know the possible causes, and they are already mentioned in the previous answers, but I don't allocate memory, don't access array elements, don't return pointers to local variables...

我对这个错误困惑了好几个小时,我知道可能的原因,并且它们已经在前面的答案中提到过,但是我不分配内存,不访问数组元素,不返回指向局部变量的指针.. .

Then finally found the source of the problem:

然后终于找到了问题的根源:

*x++;

The intent was to increment the pointed value. But due to the precedence ++comes first, moving the xpointer forward then *does nothing, then writing to *xwill be corrupt the stack canary if the parameter comes from the stack, making VS complain.

目的是增加指向值。但是由于优先级++在前,将x指针向前移动然后*什么也不做,*x如果参数来自堆栈,则写入将破坏堆栈金丝雀,使VS抱怨。

Changing it to (*x)++solves the problem.

更改它以(*x)++解决问题。

Hope this helps.

希望这可以帮助。

回答by zar

I usually follow the variable beforethe complaining variable which usually helps me get the problem. But this can sometime be very complex with no clue as you have seen it. You could enable Debug menu >> Exceptions and tick the 'Win32 exceptions" to catch all exceptions. This will still not catch this exceptions but it could catch something else which could indirectly point to the problem.

我通常在抱怨变量之前跟踪变量,这通常可以帮助我解决问题。但这有时可能非常复杂,正如您所看到的那样毫无头绪。您可以启用调试菜单>>异常并勾选“Win32异常”以捕获所有异常。这仍然不会捕获此异常,但它可以捕获其他可能间接指向问题的东西。

In my case it was caused by library I was using. It turnout the header file I was including in my project didn't quite match the actual header file in that library (by one line).

就我而言,它是由我使用的库引起的。结果我在我的项目中包含的头文件与该库中的实际头文件不太匹配(一行)。

There is a different error which is also related:

还有一个不同的错误也与之相关:

0xC015000F: The activation context being deactivated is not the most recently activated one.

0xC015000F:被停用的激活上下文不是最近激活的上下文。

When I got tired of getting the mysterious stack corrupted message on my computer with no debugging information, I tried my project on another computer and it was giving me the above message instead. With the new exception I was able to work my way out.

当我厌倦了在没有调试信息的情况下在我的计算机上收到神秘的堆栈损坏消息时,我在另一台计算机上尝试了我的项目,但它却给了我上述消息。有了新的例外,我才能找到办法。

回答by Kyle Alexander Buan

I encountered this when I made a pointer array of 13 items, then trying to set the 14th item. Changing the array to 14 items solved the problem. Hope this helps some people ^_^

当我创建一个包含 13 个项目的指针数组,然后尝试设置第 14 个项目时,我遇到了这个问题。将数组更改为 14 个项目解决了问题。希望这可以帮助一些人^_^

回答by Ben

Here is what I do in this situation:

这是我在这种情况下所做的:

Set a breakpoint at a location where you can see the (correct) value of the variable in question, but before the error happens. You will need the memory address of the variable whose stack is being corrupted. Sometimes I have to add a line of code in order for the debugger to give me the address easily (int *x = &y)

在错误发生之前您可以看到相关变量的(正确)值的位置设置断点。您将需要堆栈被破坏的变量的内存地址。有时我必须添加一行代码才能让调试器轻松地给我地址 (int *x = &y)

At this point you can set a memory breakpoint (Debug->New Breakpoint->New Data Breakpoint)

此时可以设置内存断点(Debug->New Breakpoint->New Data Breakpoint)

Hit Play and the debugger should stop when the memory is written to. Look up the stack (mine usually breaks in some assembly code) to see whats being called.

点击播放,当内存被写入时,调试器应该停止。查看堆栈(我的通常会在某些汇编代码中中断)以查看正在调用的内容。