【转】C++常见错误大全

原文转自:http://hi.baidu.com/qiou2719/item/b9eed949130ff50ec0161331

C++常见错误大全

0. XXXX "is not a class or namespace"错误
    最诡异的错误,提示意思很明显,说你写的名字既不是一个类也不是一个命名空间,虽然我C++水平不是很高,但再愚笨也不至于连类的格式class MyClass{....};也写不明白吧,报此错误原因显然跟它没关系,那又是怎么回事呢?
    答案是:#include   "stdafx.h"没放在代码最开头!!!
     stdafx.h知识简单说一下:
     所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC 标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。
    预编译头文件通过编译stdafx.cpp 生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。
    没把:#include   "stdafx.h"放在代码最开头会发生什么问题呢?编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,它会跳过#include"stdafx. h"之前的指令,使用projectname.pch 编译这条指令之后的所有代码。因此,当然会出现找不到类的错误了。
因此,所有的CPP 实现文件第一条语句都应该是:#include "stdafx.h"。

一.LINK2001错误:

此类错误VS给出提示但双击不会定位到出错地点,提示也莫名其妙,要究其原因排错

(1)error LNK2001: unresolved external symbol "void __cdecl GameShutdown(void)" ()

原因:头文件(如main.h)声明了方法GameShutdown(),但main.cpp里没有实现它。

排错:在工程中搜“GameShutdown”,定位在哪个.h文件,再在对应的.cpp文件中添加实现方法。

(2)子类未实现父类纯虚函数错误:

D3DRenderer.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CD3DRenderer::SetMultiTexture(void)" ()
Debug/GameProject4.exe : fatal error LNK1120: 1 unresolved externals

原因:同上,在D3DRenderer.cpp(D3DRenderer.obj对应相应的.cpp)中未实现虚方法SetMultiTexture(),这个虚方法是在类的CD3DRenderer的父类中声明,虚方法一定要实现,否则会出现unresolved externals错误

排错:简单,在类CD3DRenderer(D3DRenderer.cpp)中实现这个虚方法既可。

//C++ 子类没有实现父类的纯虚函数,则子类也变成抽象类,子类也不能实例化对象
/*在设计基类的时候不好确定将来的行为具体应该表现什么行为,但是必须的。
含有纯虚函数的类叫抽象类。抽象类不能实例化它的对象,只能为它的派生类服务。
如果子类没有实现父类的纯虚函数,则子类也变成抽象类,它也不能实例化对象。
*/

二、LINK2019 无法解析外部符号"__declspec(dllimport)“的错误

错误 1 error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall CEGUI::OgreCEGUIRenderer::OgreCEGUIRenderer(class Ogre::RenderWindow *,unsigned char,bool,unsigned int,class Ogre::SceneManager *)" (),该符号在函数 "protected: virtual void __thiscall MouseQueryApplication::createScene(void)" () 中被引用 SampleAPP.obj

经典的找不到dll错误,程序调用的方法在dll中定义,解决方法有两步:

1.找到此dll文件,还有对应的同名lib(如果是静态链接库),根据上述错误为OgreCEGUIRenderer开头的dll文件中,找到后放到你的工作空间(大概是\bin)目录下。

2.如果还是没有解决,那么一定是项目里没有引用相应的lib文件,因为别人的程序代码没有问题但是程序设置里添加了lib文件你可能没有设置,你可以在项目属性-》链接器-》输入-》附加依赖项里添加相应的lib,或者一劳永逸的方法是在程序代码的开头(#include下面)指定:

#pragma comment(lib,"CEGUIBase_d.lib")

这与在项目属性设置是一样的效果,但是会更醒目,第三方用户拷入你的代码不会再出现找不到dll的错误

三、程序中读取磁盘遇到找不到图片,资源文件引起的错误,或调用某个复杂SDK函数失败返回

此类错误vs中不会给出提示,排错很困难,在编程时在可能出错的地方要养成多MessageBox的好习惯

不良写法 if(!m_Device) return; // 如果m_Device创建失败就返回,可是下面的代码不执行,这不是我们想要的

正确写法 if(!m_Device)

{

Messagebox(0, "!m_Device", 0, 0);  return;  //这里可知道程序无故返回是因为m_Device创建失败造成的

}

四、程序中编译通过运行时却出错退出,警告框“某exe 在XXXXXX处出现未处理的异常”

这是最难调的BUG,很多错误只有运行时才暴露,这时需要借助VS中的堆栈监控来查错。

例:运行时弹出 “couldn‘t add <id, 4002201> twice, Continue?”
         点“否”让程序中断,VS弹出 "Client.exe 在 XXXXXX处出现未处理的异常,是否中断?"点击中断。
  这时打开“调用堆栈”视窗,看到绿色箭头停在哪儿就是哪地方出现的错误,但是一般它停的地方都是WIN API的低层,你是看不出来哪儿有问题,就向堆栈底部找,就是向列表下面找,看是谁调用了出错的方法函数,一步一步找。这时我找到:
  VarContain.Add(XX, XX) 看来是这儿加载时出错,某一关键字段加载了两次,但仍看不出哪儿重复加载,这时再向堆栈底部找。
  SkillProtoData->LoadFromFile(strFilename, .......) 看来是这儿加载文件有问题,用debug监视查看strFileName的文件名和路径,是“skillProtoName.xml”文件,去打开它,果然,文件里“id = 4002201”项有两条,删去一个重复项问题就解决了。

结论:当出现“某exe 在XXXXXX处出现未处理的异常”这样恐怖错误时,堆栈的帮助很重要!!!

四.error LNK2019: 无法解析的外部符号 [email protected],该符号在函数 ___tmainCR...

一,问题描述
MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 [email protected],该符号在函数 ___tmainCRTStartup 中被引用 
Debug\jk.exe : fatal error LNK1120: 1 个无法解析的外部命令

error LNK2001: unresolved external symbol [email protected]
debug/main.exe:fatal error LNK 1120:1 unresolved externals 
error executing link.exe;

二,原因及解决办法
产生这个问题的真正原因是c语言运行时找不到适当的程序入口函数,

一般情况下,如果是windows程序,那么WinMain是入口函数,在VS2008中新建项目为“win32项目”

如果是dos控制台程序,那么main是入口函数,在VS2008中新建项目为“win32控制台应用程序”

而如果入口函数指定不当,很显然c语言运行时找不到配合函数,它就会报告错误。

修改设置适应你的需求

如果是windows程序:

1.菜单中选择 Project->Properties, 弹出Property Pages窗口

2.在左边栏中依次选择:Configuration Properties->C/C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_CONSOLE, 添加_WINDOWS.

3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为Windows(/SUBSYSTEM:WINDOWS)

如果是控制台程序:

1.菜单中选择 Project->Properties, 弹出Property Pages窗口

2.在左边栏中依次选择:Configuration Properties->C/C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_WINDOWS, 添加_CONSOLE.

3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为CONSOLE(/SUBSYSTEM:CONSOLE)

五、**.exe 中的 0x111552a1 处未处理的异常: 0xC0000005: 读取位置 0x00000018 时发生访问冲突

在Ogre::ResourceGroupManager::getSingleton().addResourceLocation( "resource\gui.zip", "Zip", "GUI"); 处程序中断

提示又是像外星文天书一般晦涩,看来排错成功希望渺茫。上网查查看人家说,0xC0000005一般表示空指针,加这里涉及到读取资源可以猜测可能路径不对。果然相对路径"resource\gui.zip" 改成绝对的"d:\\gui.zip",就正常了,但是放在工程目录下还是有问题 ,那这个相对路径是相对哪儿的呢?工作空间难道设置的有问题吗?

查“项目属性”->“调试”->"工作空间" 设置是“..\bin\Debug”, 退回上级目录进入此目录一看,果然没有“resource”文件夹。在此新建一个“resource”文件夹,再放一个“gui.zip”文件放进去,再编译,还是报错,仔细检查,改成“resource\\gui.zip”,结果终于编译成功了!

心得: 所谓工作空间就是相当于传统意义的工程文件夹,所以相对路径都是相对此目录的,而不是你想当然的程序目录。还有程序代码写路径时一定要双划线,切记!

六、error C2360: initialization of ‘c‘ is skipped by ‘case‘ label

void   func(   void   )   
{   
        int   x;   
        switch   (   x   )   
        {   
        case   0   :   
              int   i   =   1;               //   error,   skipped   by   case   1       
              {   int   j   =   1;   }       //   ok,   initialized   in   enclosing   block   
        case   1   :   
              int   k   =   1;               //   ok,   initialization   not   skipped   
        }   
}  
在switch语句内定义一个变量的时候,如果不在一个语句块内,它是直到遇到switch的"}"才结束的。

所以,如果有在case内定义新变量,最好将该条case内的语句加上{}构成语句块,避免出错
要么就不在case内定义变量,要定义整个case加上{}

七、“UINT WM_MY_REGISTERED_MSG” 已经在“XXX.obj”中定义
#pragma once不能解决头文件重复定义变量

咋一看,分明是UINT WM_MY_REGISTERED_MSG变量在XXX.cpp中重复定义了,可是搜遍整个工程,只发现 WM_MY_REGISTERED_MSG只在userMsg.h头文件中定义一处:UINT WM_MY_REGISTERED_MSG; 别处再无定义,这是怎么回事呢?
想起以前有位恩师反复告诉过我,头文件中只适合#define 常量和声明类和结构体的结构,不适合定义变量,要定义变量都要在.cpp中定义。那我试试把UINT WM_MY_REGISTERED_MSG放在主文件userMsg.cpp中,果然没错了。

看来是头文件多处包含惹的祸,虽然头文件已经写了#pragma once能解决头文件重复包含,但不能解决重复定义变量。在一个头文件中定义了一个变量,哪怕是再不起眼的int n;只要这个头文件被多个cpp #include,那这个int n就算是重复定义,就会报XXX 已经在 XXX.obj中定义的怪现象。

结论:
头文件中只能声明结构,万万不可以定义变量!!!!

八、VS2005编译DLL错误 error C2491: "XXXXXX": definition of dllimport function not allowed
dll头件:dll_object.h
#ifdef DLL_OBJECT_EXPORT
#define DLL_OBJECT_API __declspec(dllexport)
#else 
#define DLL_OBJECT_API __declspec(dllimport)
#endif
DLL_OBJECT_API void FuncInDll(void);
extern DLL_OBJECT_API int g_nDll;
class DLL_OBJECT_API CDll_Object
{
public:
 CDll_Object(void);
 void show(void);
};

dll_object.cpp:
#define DLL_OBJECT_EXPORTS
#include <Windows.h>
#include <iostream>
#include "dll_object.h"
using namespace std;

DLL_OBJECT_API void FuncInDll(void)
{
   cout << "This is FuncInDll"<<endl;
}

DLL_OBJECT_API int g_nDll = 9;

CDll_Object::CDll_Object()
{
 cout << "class of CDll_Object" << endl;
}

void CDll_Object::show()
{
 cout<<"function show in class CDll_Object"<<endl;
}
这样写完全没问题,但是老是报error C2491: "XXXXXX": definition of dllimport function not allowed 错,解决方案:
改变VS2005的编译器生成的预定义宏。
我建立的项目名字是MyClass,系统就自定义生成了MyClass_EXPORTS,改成程序中用到的DLL_OBJECT_EXPORTS就能编译通过了

八. A buffer overrun has occured
缓冲区溢出,可能是数组越界,范围太小而存的东西太多升造成

九.

fatal error CVT1100: duplicate resource. type:MANIFEST, name:1, language:0x0409
解决办法:在工程的rc文件中,搜索类似 RT_MANIFEST             "res//TestApp.manifest",然后删除掉就OK了

十、头文件相互包含导致的错误
例,有一个状态类
#include "Player.h"
class
State
{
public:
 virtual void execute(Player*
mutou);
};
Player类
#include "State.h"
class
Player
{
 public:
   void changeState(State*
curState);

}
编译时Player始终报Sate符号错误,说明类Sate有问题,可是看类State就是看不出什么毛病,看了半天才知道,原来State需要用到Player类,而Player又要用到State类,两者相互包含导致一个无解的死循环,所以报错
那怎么办,就真的无解了吗?肯定不是,可以用指针+类声明解决,
State类把include "Player.h"去掉,改成这样
class Player;  //要用到的类事先声明
class
State ...//下面的和以前一样

然后在State.cpp里再包含 Player.h就可以了,这样就解决了头文件互相包含的问题, Player.h也作相应处理

注意此法只能适应头文件里包含的类是指针形式,如void execute(Player* mutou);,如果参数不是用指针而是实例如 void
execute(Player player)就不行了
总体原则上头文件尽量在.cpp里包含,当然避免不了的就采用这种class
XX事先声明+指针的形式来解决

时间: 2024-10-18 07:44:08

【转】C++常见错误大全的相关文章

2019-6-18 MySQL常见错误大全(陆续更新)

MySQL常见错误大全--使用环境C7.4+MySQL5.7.20一 安装并初始化mysql数据库时可能出现的错误1.执行初始化数据库时报错: mysqld --initialize-insecure --user=mysql --datadir=/data/3307/data --basedir=/usr/local/mysql 跳出如下错误: /usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.s

ASP.NET常见错误大全

1.检测到有潜在危险的 Request.Form 值 原因: (1)在提交数据的页面或webconfig中没有对validateRequest的属性进行正确的设置 (2)HTML里面写了两个<form>引起 解决: 方案一: 在.aspx文件头中加入这句: <%@ Page validateRequest="false" %> 方案二: 修改nfig文件: <configuration> <system.web> <pages va

如何用 Android Studio 导入开源项目以及常见错误的解决办法

声明:这篇文章完全来自这篇文章,感谢大神的相助.这篇文章纯粹是为了备份. 本篇以Github上最热门的MaterialDesign库,MaterialDesignLibrary来介绍怎样使用Android Sudio导入开源项目的,如果你和我一样刚刚从Eclipse转到AS,那本篇文章非常适合你. 如果不引入任何第三方库,不做自动化分渠道打包等操作,那可以在完全不了解Gradle的情况下进行Android项目的开发.但如果要想导入Github上的热门项目,必须首先熟悉Gradle. 1. Gra

MySQL主从多种架构部署及常见错误问题解析

本文的主要内容有mysql复制原理,mysql一主多从.双主架构的示例解读,以及mysql在主从复制架构实践中的常见错误问题和解决方法. 一 mysql复制原理 1 原理解读 mysql的复制(replication)是异步复制,即从一个mysql实列或端口(Master)复制到另一个mysql实列的或端口(slave):复制操作由3个进程完成,其中2个(SQL进程和I/O进程)在Slave上,另一个在Master上:要实现复制,必须打开Master端的二进制日志(log-bin),log-bi

coreseek常见错误原因及解决方法

coreseek常见错误原因及解决方法 Coreseek 中文全文检索引擎 Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和信息处理领域,适用于行业/垂直搜索.论坛/站内搜索.数据库搜索.文档/文献检索.信息检索.数据挖掘等应用场景,用户可以免费下载使用 本文为大家整理了coreseek/sphinx中文检索引擎的常见问题和解决方法,感兴趣的同学参考下. Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协

Socket常见错误

一.简介 本文介绍 Socket 连接常见错误.   二.常见错误 1)ECONNABORTED 描述:"software caused connection abort",即"软件引起的连接中止" 原因:当服务和客户进程在完成用于 TCP 连接的"三次握手"后,客户 TCP 发送了一个 RST (复位)   2)ECONNRESET 描述:"connection reset by peer",即"对方复位连接&qu

telnet常见错误及其解决方法

telnet常见错误提示及解决方法 当出现以下问题时,即软件已安装.服务已经启动,查看23号端口却发现,没有此端口,解决方法如下:修改telnet服务配置文件. [[email protected] ~]# rpm -qa telnet* telnet-server-0.17-48.el6.x86_64 telnet-0.17-48.el6.x86_64 [[email protected] ~]# service xinetd start 正在启动 xinetd: [[email protec

Linux 源码安装apache 与常见错误解决

文档原位置 一.编译安装apache 1.解决依赖关系 httpd-2.4.4需要较新版本的apr和apr-util,因此需要事先对其进行升级. 升级方式有两种,一种是通过源代码编译安装,一种是直接升级rpm包(谨慎!小心).下面是使用源代码的方式行,它们的下载路径为:(~_~)这里不再说到那里下载了,相信你有能力找的到的,呵呵 2.安装依赖的软件包(当然这里可以认为成需要的编译环境咯!) yum -y install pcre-devel yum -y install  "Developmen

iOS开发——错误总结篇&amp;开发中常见错误和警告总结(三十三)

开发中常见错误和警告总结(三十三) 动画冲突 错误: Unbalanced calls to begin/end appearance transitions for <uivewcontroller> 解决方法1:去掉动画 解决方法2:监听当前view的动画是否完成 解决方法就是,加一个BOOL型的变量,检查是否在做动画. 1 2 if (transiting) { 3 return; 4 } 5 transiting = YES; 6 [self transitionFromViewCon