Jen*_*lom 3 c++ visual-studio c++11
我碰到一个访问冲突来到同时阅读位置0xFEEEFEF6在Visual Studio 2012(使用2012年11月CTP编译)深的地方的C++ 11并发里面执行.
这个值有什么特别的含义吗?在Wikipedia中查找我发现了类似的条目(0xFEEEFEEE和0xFEEDFACE).
0xFEEEFEF6本身没有特殊含义,但它可能基于MSVC喜欢围绕堆分配的"保护字节"段之一.正如Jan Dvorak所指出的那样,它可能超过了某个结尾的8个字节,很可能是超过数组末尾的2个指针.
这个概念是你可能偶然访问的内存,但不应该,标记非常明显的模式.一些最常见的是0xCDCDCDCD和0xFDFDFDFD,虽然0xDDDDDDDD和0xFEEEFEEE也很容易碰到.经典编译器(不确定是否仍然使用它)喜欢0xDEADBEEF.这是一个非常好的案例和位置的记录,你会看到保护字节.
在段错误(访问冲突)中看到这些的两个最常见的原因通常是访问已经释放并超出边界的内存,尤其是在指针数组中.用于保护数据的大多数值如果要在应用程序中显示则无效(否则您将不会获得内存块,0x00000000或者0xCDCDCDCD这些值远远超出您的堆所在的虚拟地址空间) ).了解常见问题可以节省大量的调试时间.
请注意,只有极少数/无异常,这些保护字节仅出现在调试版本中.每次分配/解除分配时使用特殊模式写入内存(事实上,写入的内存比已分配的内存大得多,因为大多数保护模式出现在分配的块的边界上)是相当昂贵的,不应该在运行时完成.如果在调试版本中遇到类似这样的问题,则可能会从发布版本中获得看似随机(未定义)的地址.您可能也会感到不幸的是,合法地址最终被错误地抓取,这可能导致各种堆损坏.
由于保护字节不会在发布版本中显示,因此您无法检查它们,NULL并将其用作代码中的条件.相反,智能指针和容器可以帮助您正确管理内存并避免错误访问.虽然偶尔会很烦人,但智能指针非常有助于避免这样的问题.请注意,某些类型的访问冲突(特别是缓冲区溢出)被视为一整类安全漏洞,因为它们出现的频率.
如果没有VM /运行时强制您保持在某些内存限制内,如果可以非常容易地访问内存,则不应该这样做.例如:
int values[10];
int output = 0;
int length = 10;
while (int i <= length) {
output += values[++length];
}
Run Code Online (Sandbox Code Playgroud)
前缀增量将导致您运行数组的末尾并访问values[10]无效索引.有时,这可能会立即导致访问冲突并暂停您的程序,有时可能是您可以访问的内存并且将添加该值output,这可能会导致output应用程序的其余部分出现溢出和意外行为.
保留字节存在,以便您的段错误或增量在调试时具有可重复的值并尽可能明显.
| 归档时间: |
|
| 查看次数: |
1347 次 |
| 最近记录: |