博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C/C++常见错误

Posted on 2019-01-02 19:39  不上班行不行  阅读(412)  评论(0编辑  收藏  举报

1.段错误

段错误:指的是访问了不可访问的内容,内存要么是不存在的,要么是受到系统保护的。

如:1.释放了不存在的内存(堆内存)

    int a = 5;
    free a;

2.代码被重复定义了

往往是由于头文件被重复定义了。可以使用宏定义来解决。xxx可以是任意变量名

    #ifndef xxx
    #define xxx
    添加你所定义文代码
    #endif

3.forward declaration(前置声明)

当想要使用一个类型的时候除了包含头文件外还可使用含前置声明。并且只能把该类型声明为指针或者引用,不能进行初始化也就是说在没有定义之前都无法使用。这个时候编译器只知道了类型,根本不知道它的大小等信息。这也是为什么不能声明为普通变量的形式,因为编译器无法对其进行初始化(incomplete type)。使用前置声明时,往往多用于函数参数中。

test1.h

class A{

public:

  void say();

};

test2.h

class A;

class B{

  public:
  A* a_;
  void say(A* a);

}

可以看到类B使用了类A,除了引入头文件外还以使用前置声明即在class B{}上面添加“class A;"便可。在之后的test2.cpp中必要包含test1.h才能对class A进行定义,然后进行使用,如

#include "test2.h"

#include "test1.h"

void B::say(A* a){

   a->say();

}

使用前置声明的方式加强了类的可读性,能够适当减少繁琐的#include,以及改善头文件相互包含引起的问题。这类问题要记住:在声明时可以只需要知道类型,使用时必须进行了定义。

4.头文件之间的相互包含问题

在定义头文件的时候一定要记住使用条件预编译语句,防止重复包含

#ifndef TEST

#define TEST

//your content

#endif      

test1.h

#ifndef TEST1

#define TEST1

#include "test2.h"

class A{

public:

      B* b;

};

#endif

test2.h

#ifndef TEST2

#define TEST2

#include "test1.h"

class B{

  public:
  A* a_;
  void say(A* a);

}

#endif

此时展开test1.h会得到

#ifndef TEST1

#define TEST1

class B{

  public:
  A* a_;
  void say(A* a){
      a_ = a;
  }

}

class A{

public:

      B b;

};

#endif

可以看到class B的定义是在class A之前定义的,B中又对A进行了声明,这个时候只需要在test2.h中使用前置声明(class A)便可以编译过test1.h。编译test2.h同理,test1.h中使用前置声明(class B)。