当您使用指针在堆上分配动态内存时,
char *buffer_heap = new char[15];
Run Code Online (Sandbox Code Playgroud)
它将在内存中表示为:
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««þþþ
Run Code Online (Sandbox Code Playgroud)
为什么最后没有一个NULL终止字符而不是««««««««þþþ?
如果您想查看此问题的原始表现,请阅读"原始问题"部分.
简而言之:我正在修改C++联合对象的一个字段,但这对其他字段没有任何影响,它的表现非常像一个结构.对于解决方案:请参阅我的回答.
tl; dr:不QueryPeformanceCounter应该QuadPart在提供的字段中返回它的值LONG_INTEGER而不是HighPart/ LowPart?我无法找到任何特定于系统的地方,但似乎是这样.
我从Windows获得了一种奇特的行为QueryPeformanceCounter.仔细考虑这个非常简单的用法,紧跟微软的例子:
#include <windows.h>
bool test()
{
LARGE_INTEGER start, end, freq;
if (!QueryPerformanceFrequency(&freq)) {
cout << "QueryPerformanceFrequency failed!\n";
return false;
}
QueryPerformanceCounter(&start);
Sleep(1000); // Simulate work
QueryPerformanceCounter(&end);
cout << "range: from " << start.QuadPart << " to " << end.QuadPart << endl;
return true;
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
range: from -3689348814741910324 to -3689348814741910324
Run Code Online (Sandbox Code Playgroud)
这似乎很随意,但事实并非如此.添加转储功能:
ostream& operator << (ostream& os, const LARGE_INTEGER& li) …Run Code Online (Sandbox Code Playgroud) 我正在调试一个缺陷,并将其缩小到对象的vtable指针0xdddddddd. 这个答案表明Win32调试版本通常会将死记忆或已删除的内存设置为此特殊值.
需要注意的是指针本身看起来有效,它只是虚函数表指针是0xdddddddd.
这是一段代码:
std::list<IMyObject*>::const_iterator it;
for (it = myObjects.begin(); it != myObjects.end(); ++it)
{
IMyObject* pMyObject = *it;
if (pMyObject == 0)
continue;
pMyObject->someMethod(); // Access violation
}
Run Code Online (Sandbox Code Playgroud)
如果我在访问冲突的行中断并观察pMyObject,我可以看到它pMyObject本身有一个有效的地址(0x08ede388)但该__vfptr成员是无效的(0xdddddddd).
一些说明:
有关如何进一步调试的任何建议?
在过去的两天里,我一直陷入违规行为,我似乎无法逃脱.我已经使用了断点并找到了错误的位置,但我只是希望你们中的一个人知道问题是什么而我不必复制+粘贴我的所有代码 - .-
我越来越
Escape.exe中0x1027cb1a(msvcr100d.dll)的第一次机会异常:0xC0000005:访问冲突写入位置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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在myMap是一个类型为Tile的二维数组.几天前,我有这个工作,直到我添加了一些其他类,这一切都停止了工作!
我有一个指向给定类的指针.可以说,例如,指针是:
0x24083094
Run Code Online (Sandbox Code Playgroud)
该指针指向:
0x03ac9184
Run Code Online (Sandbox Code Playgroud)
这是我班级的虚拟功能表.这对我来说很有意义.在windbg中,一切看起来都是正确的.
我删除了指针.现在0x24083094是:
0x604751f8
Run Code Online (Sandbox Code Playgroud)
但它不是一些随机垃圾,每次都会放在那里,它始终如一0x604751f8!这么多,以至于我可以实际使用该地址来确定是否删除了我的应用程序执行之间的指针!
但为什么?它如何确定0x604751f8应该写在那里?
为了记录,我正在使用Windows,在visual studio 2003下构建.
我知道我不能依赖于设定的值,即使它确实看起来是一致的,但我能依靠它不同吗?即,如果指针被删除,0x03ac9184将不会0x24083094,对吗?什么放在那里?它可能是任何东西,但0x03ac9184肯定不会存在(或者我仍然可以调用方法,因为那是虚函数表).我对吗?
我觉得我有答案.删除后不能依赖任何东西.也许一些背景会帮助人们看到我来自哪里.从本质上讲,我正在尝试修复一个错误,指针从我身下被删除.这是一个很长的故事,我不会详细介绍.
基本上,我试图检测到我处于这种情况,所以我可以优雅地退出我的功能.我想最简单和最好的方法是弄清楚谁实际拥有这个指针,然后问他是否有任何改变.所以我要实现这样的修复.它避免了我正在讨论的任何这个C++删除黑客.
然而,有趣的是,在我们的代码中,我们有一个名为"BogusObject"的类,它基本上充当一个托盘,捕捉那些意外取消引用释放对象的人.基本上,我们挂钩我们自己的删除函数,并将BogusObject类bash到任何释放类的vtable中.
然后,如果有人打电话给他们,他们会收到一条好消息说"嘿,有些事情是错的.".这种情况发生在我的情况下.即,0x604751f8+(someoffset)在BogusObject类中. 但是我们不再使用BogusObject了! 它确实没有在任何地方设置(如果我完全删除了BogusObject类,甚至连接正确),但我仍然得到一个好消息说错了!但我现在认为这是巧合.
由于某种原因,运行时0x604751f8在删除它时将该值放在this指针中,而这恰好与一个有类似这样的情况的类相对应!
我一直在重构一些代码,我注意到一些涉及未初始化的int数组的不稳定行为:
int arr[ARRAY_SIZE];
Run Code Online (Sandbox Code Playgroud)
我设置了一个断点,似乎所有值都默认为-858993460.这个价值有什么特别之处吗?任何想法为什么他们不默认为0?
我正在调试MS VC++ 6.0中的一些代码.出于某种原因,在我想要删除一些动态分配的内存的某个点上,它会中断并且我得到一个弹出消息框,说"用户断点从代码中调用等等",然后出现反汇编窗口,然后我弹出看到
*memory address* int 3
Run Code Online (Sandbox Code Playgroud)
奇怪的是,代码中有NOWHERE,我正在调用这样的汇编指令(我认为asm int 3是x86的硬件中断命令?)..
可能是什么导致了这个?
编辑:答案:我的代码是"走出末端"的数组,但只在Visual Studio调试标记的位置使用0xFDFDFDFD,这被称为NoMan'sLand栅栏..我认为它也称为Off-by-一个错误..这个数组与我在发生错误时释放内存的点无关.这使得发现更难.. :(
可能重复:
操作系统在malloc/free/new/delete上将内存初始化为0xCD,0xDD等的时间和原因是什么?
为什么内存我没有初始化设置为0xCC?
将内存设置为0xCC会降低性能,因此必须有一个填充内存的原因.
这就是事情.我最近在Qt框架上重写了我的OpenCV代码,并且代码在Visual Studio 2013上运行良好,但是当我在Qt上运行它时,发生了一些奇怪的事情.
为了简化问题,我编写了另一个代码来进行实验,并且预计问题仍然存在.
这是代码,
#include <iostream>
#include <highgui.hpp>
#include <core.hpp>
#include <cv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat view, viewGray;
vector<Point2f> pointBuf;
Size boardSize;
boardSize.width = 7; boardSize.height = 9;
view = imread("G:\\C++\\OpenCV\\OpenCV\\left1.jpg", 1);
cout << pointBuf.size() << endl;
cout << boardSize << endl;
cvtColor(view, viewGray, COLOR_BGR2GRAY);
bool found = findChessboardCorners(view, boardSize, pointBuf, \
CV_CALIB_CB_ADAPTIVE_THRESH | \
CV_CALIB_CB_FAST_CHECK | \
CV_CALIB_CB_NORMALIZE_IMAGE);
cout << pointBuf.size() << endl;
cout << found << endl;
namedWindow("show", CV_WINDOW_NORMAL);
imshow("show", view); …Run Code Online (Sandbox Code Playgroud) c++ ×10
debugging ×3
c ×2
visual-c++ ×2
windows ×2
calloc ×1
malloc ×1
opencv ×1
opencv3.0 ×1
performance ×1
pointers ×1
qt ×1
visual-c++-6 ×1
vtable ×1
winapi ×1