VC6中Debug调试正常运行和Release运行崩溃

转载于:http://blog.csdn.net/bzhxuexi/article/details/25460937

I. 内存分配问题

1. 变量未初始化。
为debug中会自动给变量初始化found=FALSE,而在release版中
则不会。所以尽可能的给变量、类或结构初始化。
2. 数据溢出的问题
如:char buffer[10];
int counter;
lstrcpy(buffer, "abcdefghik");
在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没
有。但是在release版中,counter可能被放在寄存器中,这样NULL就覆盖了buffer下面
的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。
3. DEBUG版和RELEASE版的内存分配方式是不同的 。如果你在DEBUG版中申请
ele 为 6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes
为单位分配), 而在release版,分配给你的就是24bytes(release版以8bytes为单位
),所以在debug版中如果你写ele[6],可能不会有什么问题,而在release版中,就有A
CCESS VIOLATE。
II. ASSERT和VERIFY
1. ASSERT在Release版本中是不会被编译的。 
假如你在这些语句中加了程序中必须要有的代

比如
ASSERT(pNewObj = new CMyClass);
pNewObj->MyFunction();
这种时候Release版本中的pNewObj不会分配到空间
所以执行到下一个语句的时候程序会报该程序执行了非法操作的错误。这时可以用VERIFY 
III. 参数问题:
自定义消息的处理函数,必须定义如下:
afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);
返回值必须是HRESULT型,否则Debug会过,而Release出错 
IV. 内存分配
保证数据创建和清除的统一性:如果一个DLL提供一个能够创建数据的函数,那么这个D
LL同时应该提供一个函数销毁这些数据。数据的创建和清除应该在同一个层次上。
V. DLL的灾难
人们将不同版本DLL混合造成的不一致性形象的称为 “动态连接库的地狱“(DLL Hell) 
如果你的程序使用你自己的DLL时请注意:
1. 不能将debug和release版的DLL混合在一起使用。debug都是debug版,releas
e版都是release版。
解决办法是将debug和release的程序分别放在主程序的debug和release目录下
2. 千万不要以为静态连接库会解决问题,那只会使情况更糟糕
VI. RELEASE板中的调试 :
1. 将ASSERT() 改为 VERIFY() 。找出定义在"#ifdef _DEBUG"中的代码,如果
在RELEASE版本中需要这些代码请将他们移到定义外。查找TRACE(...)中代码,因为这些
代码在RELEASE中也不被编译。 请认真检查那些在RELEASE中需要的代码是否并没有被便
宜。
2. 变量的初始化所带来的不同,在不同的系统,或是在DEBUG/RELEASE版本间
都存在这样的差异,所以请对变量进行初始化。
3. 是否在编译时已经有了警告?请将警告级别设置为3或4,然后保证在编译时没
有警告出现.
VII. 将Project Settings" 中 "C++/C " 项目下优化选项改为Disbale(Debug)。编
译器的优化可能导致许多意想不到的错误,请参考 http://www.pgh.net/~newcomer/deb
ug_release.htm
1. 此外对RELEASE版本的软件也可以进行调试,请做如下改动:
在"Project Settings" 中 "C++/C " 项目下设置 "category" 为 "General" 并且将"D
ebug Info"设置为 "Program Database"。
在"Link"项目下选中"Generate Debug Info"检查框。
"Rebuild All"
如此做法会产生的一些限制:
无法获得在MFC DLL中的变量的值。

必须对该软件所使用的所有DLL工程都进行改动。

//-------------------------------------------------------------------------------------------

struct ListNode{
   int val;
   struct ListNode *next;
};

void Create(int *data,int size,struct ListNode * head)
{
    //struct ListNode * head = (struct ListNode *)malloc(sizeof(struct ListNode));
	struct ListNode * Last;
	head->val = data[0];
	Last = head;
	for(int i = 1;i < size;i++)
	{
	    struct ListNode * temp = (struct ListNode *)malloc(sizeof(struct ListNode));
		temp->val = data[i];
		Last->next = temp;
		temp->next = NULL;
		Last = temp;
	}
	//return head;
}
void main()
{
    int *data;
	int size;
	scanf("%d",&size);
	data = (int *)malloc(sizeof(int));
	for(int i = 0;i < size;i++)
	{
	   scanf("%d",&data[i]);
	}
	struct ListNode * head = (struct ListNode *)malloc(sizeof(struct ListNode));
	Create(data,size,head);
	struct ListNode * RHead = head;
    while(RHead->next != NULL)
		RHead = RHead ->next;
	printf("逆置前:");
	//printf("%3d\n",head->next->next->next->val);
    Display(head);
    reverseList(head);
    printf("逆置后:");
    Display(RHead);
}

上面是我最初的错误代码,经过检查后发现出现的问题是越界的问题,也就是上面指出的内存分配的问题。因为这只是个很小的程序,所以先考虑内存的问题,一般出现指针错误可能是,访问空指针或者访问了一个不该访问的指针。其次就是指针的访问越界问题或者数组的访问越界问题,还有就是指针,变量的初始化等问题。

该程序在测试数据小于4个的时候是可以正常运行的,用例:4 4 5 1 9 ,但是一旦数据等于5个就会在最后一个出现乱码,一旦大于5个则会直接运行错误,出现崩溃的情况。但是我们可以在release版本的vc中发现正常运行,这就导致我们无法进行调试。所以我们有理由怀疑是空间分配的问题。然后我发现代码的错误行在:

data = (int *)malloc(sizeof(int));

也就是在数组申请的时候,sizeof的字节分配和内存数据占有的情况,这里本来是应该申请为size*sizeof(int)大小的字节空间才对。

总结:

1.变量是否初始化

2.指针是否出现空指针

3.指针是否指向了不该指向的地方

4.数组,指针访问是否越界

5.malloc申请的时候是否出现问题

猜你喜欢

转载自blog.csdn.net/c_living/article/details/80942130
今日推荐