【C++内存管理之三野指针、内存泄漏、内存覆盖及应对策略

本文详细探讨了C++编程中常见的内存管理问题,包括野指针(如访问权限错误和指向已释放内存)、内存泄漏(分析未释放内存的原因)以及内存覆盖(如strcpy、memcpy、strcat操作导致的问题)。同时,文章还列举了内存分配失败、越界操作等常见错误,并提出了相应的解决策略,强调了野指针与内存泄漏之间的关系,指出内存释放并不意味着指针的销毁或重置为NULL。


发生内存错误时间非常麻烦的事情。编译器不能发现这些错误,只能在程序运行时才能捕捉到。常见的内存错误有三种,野指针、内存泄漏和内存覆盖

一、野指针问题

野指针是指向了被释放或没有访问权限的内存指针。

1、访问权限

//野指针
int* p;
p = 10;
//报错,使用了未初始化的变量p

2、指向被释放的内存
在这里插入图片描述

二、内存泄漏

内存泄露(memory lock)是指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。

1、内存使用完之后,没有释放;
2、对new或malloc出的指针进行重新赋值。
内存泄漏查询方法

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
int main(){
    _CrtSetBreakAlloc();
    ....................
    _CrtDumpMemoryLeaks();
    return 0;
}

详解:
https://blog.csdn.net/daaikuaichuan/article/details/80874436

三、内存覆盖

strcpy、memcpy、strcat容易发生内存覆盖问题
1、strcpy函数

char* strcpy(char* dst, const char* src, int size) {
	assert(src);
	assert(dst);
	if (dst <= src || dst > src + size) {
		char* d = dst;
		const char* s = src;
		while (size--) {
			*d++ = *s++;
		}
	}
	else {//发生内存覆盖,逆向复制
		char* d = dst + size - 1;
		const char* s = src + size - 1;
		while (size--) {
			*d-- = *s--;
		}
	}
	return dst;
}

2、memcpy函数

void* memcpy(void* dst, const void* src, int size) {
	if (src != nullptr || dst != nullptr) {
		return nullptr;
	}
	char* d = (char*)dst;
	char* s = (char*)src;
	if (d <= s || d > s + size) {
		while (size--) {
			*d++ = *s++;
		}
	}
	else {//发生内存覆盖,逆向复制
		d = d + size - 1;
		s = s + size - 1;
		while (size--) {
			*d-- = *s--;
		}
	}
}

3、strcat函数

char* strcat(char* dst, const char* src) {
	assert(src);
	assert(dst);
	char* p = dst;
	while (*dst != '\0') {
		dst++;
	}
	while (*dst++ = *src++ != '\0');
	return p;
}

四、常见错误及对策

1、内存分配失败
内存分配失败却使用了它
指针p为函数参数,在函数入口处进行检查:

assert(p != NULL);

new或malloc申请内存进行判断:

if(p == NULL)

2、内存操作越界
常见的数组越界,发生在下标多‘1’或少‘1’;
指针超过变量范围(野指针)
3、指针越界
4、空指针
在这里插入图片描述
常见对策

规则
规则1用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
规则2不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
规则3避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
规则4动态内存的申请与释放必须配对,防止内存泄漏。
规则5用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。

野指针与内存泄漏的关系

  1. 指针销毁了,并不表示所指的空间也得到释放了: 内存泄漏!
  2. 内存释放了,并不代表指针被销毁或者指向了NULL ;未初始化的指针(野指针)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值