vc7.0常见调试问题

1)disable
#pragma warning (disable: 4311 4312)     //指针类型强制转化,大小不完全匹配
warning C4311: 'type cast' : pointer truncation from 'TriNode *const ' to 'long'    
warning C4312: 'type cast' : conversion from 'unsigned int' to 'SAC_Node_Add *' of greater size
注: 64位编程时,c4311的警告要处理,c412可以不处理.

#pragma warning (disable: 4244 4267)    //丢失数据,4244为已知类型,4267为64位类型转化
warning C4244: '=' : conversion from 'long' to 'char', possible loss of data    
warning C4267: '=' : conversion from 'size_t' to 'long', possible loss of data    

#pragma warning (disable: 4996)    //安全警告
warning C4996: 'fopen' was declared deprecated

2)MSVCR80D.dll
fat32的文件系统的时间戳有问题,ntfs分区下就没这个问题.
解决方案是:在编辑状态下,点项目菜单 -> property -> 配置属性 -> 清单工具,将右面的“使用FAT32解决办法”选为“是”即可。

3)调试参数选项
a)行号设置: Tools->Options->Text   Editor->C/C++,  display: line numbers勾选上
b)调试变量中使用10进制数字: 在调试器窗口中右击,16进制显示勾去掉.
c)工作路径: 右击工程属性页property page,General-->output directory;
d)可执行程序: 右击工程属性页property page, debugging-->command;
e)设置预编译头文件: 现象:fatal error C1010: unexpected end of file while looking for precompiled header directive,
解决方法: 右击项目工程中的该cpp文件,property page, c/c++-->precompiled headers,选择第一项,不使用预编译头文件;

4)调试DLL
不能进入到DLL的source code中,解决方法如下:
一是clean-->rebuild; 二是设置项目依赖关系; 如果不行的话,就有可能是某个文件的注释或者其它莫名其妙的原因导致出错,就对要进入的那个文件重新分析,最好恢复到上次能进入的页面看是什么导致出错.

5)64位数输出
_int64 num1;
printf("%I64d", num1);
在gcc可用%ll直接得到64位输出. typedef long long _int64;
NOTE:VC下不支持long long数据类型,只能使用MS的_int64,下面分别是vc下64的无符号,有符号,16进制输出格式
#define HOST_WIDEST_INT_PRINT_DEC       "%I64d"     
#define HOST_WIDEST_INT_PRINT_UNSIGNED  "%I64u"
#define HOST_WIDEST_INT_PRINT_HEX       "0x%I64x"

6)winsock2.h与windows.h重定义的问题
a)方案1: 在windows.h前加 宏定义WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN    //此宏用来加快加载windows.h,可以少包含一些较少使用的头文件
#include <windows.h>
b)方案2: 在 windows.h 前先 winsock2.h

7)怎么使用MFC库? (轻量级的使用).
假设: 在一个windows console程序中,后来要使用MFC的字符串模板类CString,但不需增加太多的MFC其它类.
方法:
a)先在VC项目菜单-> property -> general -> use of MFC中,选用: use MFC in a Share Dll;
b)生成一个stdafx.h,在这个头文件中,只包括
#include <afxwin.h>         // MFC core and standard components
如果使用了socket函数,则
#include <afxsock.h>        //instead of  <winsock2.h> <mswsock.h>
//其它需要添加的结构或头文件...

8)error
a)要注意变量的生存周期,在for,while语句里的变量如果下面还要使用,那么此变量要提前到语句之前申明;
b)

xx)文件IO要注意的问题
a)文件句柄: 数字的文件描述符,一个进程能打开的所有文件句柄总数是有限制的,经测试<1024(系统限制数),此外,进程关闭,所有此进程打开的文件句柄自动关闭;文件句柄是可重用的,每次得到的文件句柄一定是最小的未用的;所以同一线程不断打开关闭,可能获得句柄指针是一样的,而且线程ID也可能一样;
b)IO的效率: 最好BUFFSIZE的大小与文件块长相同,如常见的8k一块的文件系统,效率最高;
c)文件共享:内核维护三种数据结构:进程表项,文件表项,文件节点结构;此三张表构成了文件与进程之间的关系.也是理解文件读写加锁的关键; 注意每个进程都在进程表项中占有一个位置,每个进程都指向一个进程相关的打开文件表项,而每个文件维护一个文件节点结构.所以,各进程独享的变量是文件描述符,打开文件的文件状态标志,当前文件偏移位置;而每个文件的文件长度,所有者,设备,磁盘中的位置指针等是各进程共享变量.
d)文件路径:用./来表示下层目录,也可用.//来表示,/是转义符,表示'/'要用'//'.
e)锁的技巧:文件级,字节级;

f)函数的使用技巧:
  不带缓存的IO是指系统调用函数:read,write,lseek,open,close...
  lseek.fseek仅将当前文件位移量记录在内核,允许文件位移量大于文件大小,不引起IO操作,因此本函数通常不会出错,lseek是为下一步读写函数服务的.要对文件读写函数进行判断,fread,fwrite,若出错,就要关闭文件指针.每次读写操作后,位移量要进行变动,才能进行下一步操作,否则操作的是一次同一个位置,除非打开文件使用append方式.(换句言,每次读定操作写,先要定位偏移量).
  多进程读同一个文件能正常工作,因为每个进程各有自己的文件表项,当中有自己的文件位移量;但多进程同写一个文件则可能会出错,因此要把lseek,write作为一个原子操作.在windows平台,线程与进程在内核是等同的(?),所以多进程操作类似多线程.


FAQ1: 多级指针初始化
a) long* m_ltest1= new long;
b) long** m_cppValue1;    
   m_cppValue1 = new long* [3];
   for(i = 0; i < 3; i++){ m_cppValue1[i] = new long [m_lMaxDocId]; }

c) long*** m_cppValue;
m_cppValue = new long**[M];
for(i = 0; i < M; i++){
    m_cppValue[i] = new long*[N];
    for(j = 0; j < N; j++){
    m_cppValue[i][j] = new long;
    }
}
//释放内存时的顺序刚好相反,先删除最低层元素空间.
for(i = 0; i < M; i++){
    for(j = 0; j < N; j++){
    if(m_cppValue[i][j]) delete m_cppValue[i][j];
    }
    if(m_cppValue[i]) delete m_cppValue[i];
}
if(m_cppValue)    delete m_cppValue;   

你可能感兴趣的:(vc7.0常见调试问题)