您的位置:首页 > 其它

Catch Bug

2016-02-04 22:21 281 查看

1. Makefie与环境变量

编译某一源码时,我直接把LIBRARY_PATH,和LD_LIBRARY_PATH写在Makefile里,并自作聪明地加上了export。

这导致系统根本找不到库的路径。

//原因
系统环境变量可以在make开始运行时被载入到Makefile文件中。
但如果Makefile中已定义了这个变量,或是这个变量由make命令行带入,那么系统的环境变量的值将被覆盖。
(如果make指定了“-e”参数,那么,系统环境变量将覆盖Makefile中定义的变量)

比如:在环境变量中设置了“CFLAGS”环境变量,那么可以在所有的Makefile中使用这个变量了。
这对于我们使用统一的编译参数有比较大的好处。
如果Makefile中定义了CFLAGS,那么则会使用Makefile中的这个变量,如果没有定义则使用系统环境变量的值。
这类似“全局变量”和“局部变量”的特性。
(故上面的LIBRARY_PATH,和LD_LIBRARY_PATH变成了Makefile的变量)
当make嵌套调用时,上层Makefile中定义的变量会以系统环境变量的方式传递到下层的Makefile中。
默认情况下,只有通过命令行设置的变量会被传递。
定义在Makefile文件中的变量,如果要向下层Makefile传递,则需要使用exprot关键字来声明。

实际上,最好不要把许多的变量都定义在系统环境中,因为在执行不同的Makefile时,拥有的是同一套系统变量,这可能会带来更多的麻烦。


2. 除法

DWORD dwSpeed = 2;
dwSpeed = dwSpeed / 2; //区别 dwSpeed / 2.0
if ( 0 == dwSpeed )
dwSpeed = 1;
//这样求时间的时候,才没有错误
dwTime = dwDistance / dwSpeed;


3. 指针

由函数获得指针,一定要判断是否为空才能使用,无论这个指针是否智能指针

std::shared_ptr<T> pShared = getSharedPtr();
if (pShared)
{
//处理
}


4. GDB等待崩溃

服务器的程序运行后,可以直接打开“gdb -p 进程”, 等待服务器的崩溃。


5. 程序是否死循环

可以用 “top” 命令观察 当前进程消耗的计算资源


6. 浮点数间判断大小 与 判断一个浮点数是否为0.000000

(1)计算机表示浮点数(float或double类型)都有一个精度限制,

对于超出了精度限制的浮点数,计算机会把它们的精度之外的小数部分截断。

因此,本来不相等的两个浮点数在计算机中可能就变成相等的了。

例如:

A. float a=10.222222225,b=10.222222229

数学上a和b是不相等的,但在32位计算机中它们是相等的。

B. fabs(a) < eps, 则可以认为a 为0

如果两个同符号浮点数之差的绝对值小于或等于某一个可接受的误差(即精度),就认为它们是相等的。

(2) 不要直接用“==”或者“!=”对两个浮点数进行比较,

但是可以直接用“<”和“>”比较谁大谁小, 或使用库函数 std::isgreater(a, b) isgreaterequal等。

7. 浮点数累加

场景:一个1等兵(符号ARMY1)战斗力为1.11, 一个二等兵(符号ARMY2)战斗力为1.22,一个三等兵(符号ARMY3)战斗力为1.33。如何处理它们间的累加情况?

如果设总战斗力为 double sum。那么

sum = 1.11 * ARMY1 + 1.22 * ARMY2 + 1.33 * ARMY3。

如果又新增一个1等兵。那么

sum = sum + 1.11 * 1。

多次累增后,会累增浮点数间的误差。

解决方法如下:

每种兵的战斗里都乘100, 那么

int sum = 111 * ARMY1 + 122 * ARMY2 + 133 * ARMY3。

整数相加不会累加误差。当客户端需要显示战斗力时,

double show_sum = sum / 100.0。

8. probuf的解析字节大小

场景:对某一个区域,刷新城堡的时候。曾经把区域内的所有城堡信息通过repeated填充了一个probuf。当probuf的字节数量到达1.5万以上的时候,会导致客户端解析出错。

解决:每填充一定数量的repeated,就发送。

MSG_Ret_CS sendMsg

for ( int i = 0; i <n;++i)

{

  Point * p = send.add_pont();

  fill(p);

  if ( 0 == i % 10 )

  {

>    sendMsg(p);

>  send.Clear();

  }

}

//注意最后要发送剩余的

send(p);

9. string.c_str()

void doSomething(const char* str);

std::string str;
doSomething(str.c_str());


str.c_str()的生存期是由str管理的,如果str销毁,c_str()也会销毁了。-

如果doSomething()继续处理这个指针, 会导致coredump。

10. std::vector的一个误区

class A
{

};
std::vector<A>  vecArray;

vecArray.push_back(  );
vecArray.push_back(  );
vecArray.push_back(  );

A & a= vecArray.back();  //有潜在错误
vecArray.push_back(  );


vector是一个会自增长的容器,自增长的结果就是

把原来的内存释放掉,重新分配一个足够大的内存。

既然原来的内存已经释放掉,

那么a所引用的内存就是一段无效的内存。

解决方法也很多,最简单就是用std::list或者std::deque替代vecto
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Bug