您的位置:首页 > 其它

段错误和内存泄漏等问题

2021-10-26 23:10 148 查看

内存问题是C和C++程序员经常要去面对的问题,常见的内存问题主要有段错误,内存泄漏,越界访问,无效指针等

1、段错误

段错误就是指访问的内存超出了系统给这个程序所设定的内存空间,例如,访问了不存在的内存地址,访问了系统保护的内存地址,访问了只读的内存地址等情况。下面对各种情况举例说明:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void loop(){
loop();
}

int main()
{
//段错误情况1,访问了不存在的内存地址
int *p = NULL;
*p = 10;
printf("%d\n",*p);

// //这样写是正确的,因为p1指向了字符串abc的首地址
char* p1 = NULL;
p1 = "abc";
printf("%s\n",p1);

// //段错误情况2,访问了系统保护的内存地址
int *p2 = (int *)1;  //0地址为系统保护内存区域
*p2 = 100;
printf("%d\n", *p2);

//段错误3,访问了只读的内存地址,这部分段错误为最常见段错误
/*
这里是因为char* str = "abc"是存储在常量区,程序在编译的时候就分配了内存,直到程序结束才释放,
常量区的内容不能被修改,所以一旦尝试去修改就会报段错误
如果定义为char str[] = "abc" 数组存储在变量区,可对内容进行修改,就不会报段错误
*/
char *str = "abc";
strcpy(str, "def");
printf("%s\n",str);

//段错误4,栈溢出导致的段错误
/*
因为栈内存有限,由编译器自动分配释放,函数的局部变量,函数参数,返回数据,返回地址等都保存再栈空间内,
此处函数形成死循环,函数的地址最终会占满栈空间,x86系统上,内存向下增长,栈溢出到堆区,出现段错误
*/
loop();
return 0;

}

2、内存泄漏

内存泄漏并不说内存消失,而是内存申请了没有释放,导致这部分内存无法再继续使用的情况,导致了内存的浪费。如果长期内存泄漏就会导致内存溢出,内存用尽,性能不良,而且编译器并不会报错,后期查找问题的根源比较困难,所以一定代码编写时候,避免内存泄漏非常重要。
内存泄漏实例:

#include <stdio.h>
#include <stdlib.h>
int main ()
{
//内存泄漏 C语言为free的错误使用,C++为delete的错误使用
char *p = (char*) malloc(sizeof(char) * 10);
p = 'test';
printf("%s\n", p);
free(p);  // 此处出现内存泄漏,因为malloc申请的内存地址已经被修改,free的不是malloc申请的内存

//下面为C++的内存泄漏代码
char *p = new char[10];
p = "test";
cout << p << endl;
delete[] p;

return 0;
}

3、内存越界

内存越界使用会引起致命性错误,常见的内存越界有数组越界,如:Int array[10];
array[10] = 10;
还有常见的内存越界问题就是字符串赋值时出现的错误,如:
char buf[4];
strcpy(buf, "test") // 将5字节的字符串(包括'\0')拷贝给了四字节的内存空间,出现内存越界。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: