C/C++实际开发中常见问题及预防、定位方法系列(二)

  • 0

C/C++实际开发中常见问题及预防、定位方法系列(二)

前文见C/C++实际开发中常见问题及预防、定位方法系列(一)

本系列文章第二篇专门讲解C/C++最常见的内存问题

1、段错误(Linux)、程序崩溃退出(windows)

不同的系统访问非法地址时的表现不一致。本文只以最常见的Linux和Windows为例。 在Linux中,出现段错误时,可以确定是使用了非法内存。 在Windows中,出现程序崩溃,弹窗提示某个地址不能为Read,也可以确定。

下面列举一些常见的照成此类问题的原因

a、内存越界 这是一个比较常见的引起段错误或者程序崩溃的原因。当然,内存越界也会出现其它症状,这个我们之后讨论。

char acBuf[16] = {0};

char *p = “abcdefghijklmnopqrstuvw”;

strcpy(acBuf,p);

以上是一个典型的内存越界的代码。

b、没有对指针分配地址 这个是初学者容易犯的错误,大部分有经验的工程师都不会写出这样的代码

eg:

char *p;

strcpy(p,”abc”);

c、使用了只读的内存 在C/C++编译时内存可分为4大类:栈、堆、全局数据段、只读数据段 没有static修饰的局部变量获得的内存在栈上,栈上的地址系统自动回收,不用程序主动释放 用new或者malloc申请的内存在堆上,需要程序主动回收 static修饰的局部变量或者全局变量存放在全局数据段,内存一直占用,不可释放。 常量存放于只读数据段用于。

eg:

char *p=”abcdefg”;

strcpy(p,”123″);

d、使用了已释放的内存 这样也可能不会引起问题,这取决于系统收回内存后是否再次分配。 eg:

char *p= (char *)malloc(1024);

free(p);

strcpy(p,”123″);

e、多次释放内存

eg:

char *p= (char *)malloc(1024);

free(p);

free(p);

2、内存泄露

内存泄露在短暂的运行或者调试时很难发现。在长期运行后会逐渐拖慢系统的速度,直至系统崩溃。 要发现也很容易。Linux中使用top,Windows中使用tasklist指令观察进程占用的内存是否一直在增长。 造成内存泄露的原因基本上都是没有释放资源,如下例:

int a() {

char *p= (char *)malloc(1024);

}

int main() {

while(1) {

a();

}

return 0;

}

3、变量实际值与预测值不一致

除了程序本身的逻辑错误以外还有一个原因可能会导致这种情况发生,内存越界。

eg:

int a() {

int a = 0; char acBuf[4]={0};

strcpy(acBuf,”1234567891111111111111″);

printf(“%d\n”,a);

}

事实上像例子中的问题还是很好定位的,但是在现实中往往有在某个地方越界,导致很远的地方段错误或者值错误,这类问题定位非常困难,所以养成一个良好的习惯才是最主要的。


About Author

深圳市闻道软件有限公司

闻道软件工作室

Leave a Reply