1.什么操作会导致内存泄漏
指针指向改变,未释放动态分配内存
2.如何防止内存泄漏
将内存分配封装在类中,构造函数分配内存,析构函数释放内存;使用智能指针
3.对于智能指针的了解
智能指针是为了解决动态分配内存导致内存泄漏和多次释放统一内存所提出的,C11标准中方在<memory>头文件。包括:共享指针、独占指针和弱指针
4.构造函数和析构函数要设置成虚函数吗,为什么
构造函数不需要,虚函数的调用是在部分信息下完成工作的机制,允许我们只知道接口而不知道对象的确切类型。要创建一个对象,需要知道对象的完整信息(特别是类型)。
析构函数需要,当派生类对象中有内存需要回收时,如果析构函数不是虚函数,不会触发动态绑定,只会调用基类的析构函数,导致派生类资源无法释放,造成内存泄漏。
5.实现内存拷贝函数
char* strcpy(char* strDest, const char* strSrc);
char* strcpy(char *dst,const char *src) {// [1]
assert(dst != NULL && src != NULL); // [2]
char *ret = dst; // [3]
while ((*dst++=*src++)!='\0'); // [4]
return ret;
}
原字符串用const修饰,防止修改源字符串
空指针检查用assert(!dst && !src)注重代码的健壮性。
char* ret = dst;保存原始的strdst地址
6.实现string原型的函数
原型如下:
class String{
public:
String(const char *str = NULL);
String(const String &other);
~String(void);
String & operator=(const String &other);
private:
char *m_data;
};
构造函数:
String::String(const char *str = NULL){
if(str == NULL){
m_data = new char[1];
*m_data = '\0';
}else{
int length = strlen(str);
m_data = new char[len + 1];
strcpy(m_data, str);
}
}
析构函数:
String::~String(void){
delete [] m_data;
}
拷贝构造:
String::String(const String &other){
int length = strlen(other);
m_data = new char[length + 1];
strcpy(
}
赋值函数:
String& String::operate=(const String &other){
if(this == other){
return *this;
}
delete [] m_data;
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
return *this;
}
7.进程的地址空间分布
命令行参数和环境变量、栈区、文件映射区、堆区、BSS段、数据段、代码段
7.C/C++内存分配方式
(1)从静态存储区域分配
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量,static变量。
(2)在栈上创建
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有
限。
(3)从堆上分配(动态内存分配)
程序在运行的时候.malloc或new申请任意多少的内存,程序员负责在何时用free或delete释
放内存。动态内存的生存期自己决定,使用非常灵活。