在学习c++的过程中涉及到了new和delete的问题,了解过程中发现了一些关于xcode堆内存分配机制的特性
#include <iostream>
#include <cstring>
class Node {
private:
char * name ;
int number ;
static int count ;
public:
Node(int a,char * name = NULL) ;
~Node() ;
void print() ;
};
int Node::count = 0 ;
Node::Node( int a,char * n):number(a){
if (n==NULL) {
name = new char[8];
strcpy(name, "no name") ;
}else{
name = new char[strlen(n)+1] ;
strcpy(name, n);
}
Node::count +=1 ;
std::cout<<this->name<<"调用了构造函数"<<std::endl;
}
Node::~Node(){
Node::count -=1 ;
std::cout<<this->name <<"调用了析构函数"<<std::endl ;
delete this->name ;
}
void Node::print(){
std::cout<<this->number<<" "<<std::endl ;
}
int main (){
Node *b = new Node(232653,"kjk") ;
delete b ;
Node * c = new Node(21312,"c") ;
b->print();
return 0 ;
}
在这段代码中 我定义了一个类 并且先后手动分配了b,c的储存空间 。
我在给添加数据之后delete了b(注意这里并没有将b指向nullptr)然后为c分配了内存空间
在输出b的时候得出了如下结果
kjk调用了构造函数
kjk调用了析构函数
c调用了构造函数
21312
Program ended with exit code: 0
用b指针访问内存空间会输出c的数据
因为指针中储存的内存地址并没有改变 因此b指向的内存地址仍然是之前被delete掉的内存地址
而且输出了c的数据 说明这块内存被分配给了c,也就是说b和c指向了同一块内存空间,说明xcode编译器对堆的内存分配是有序的
delete在这里只是告诉编译器这块内存可以重新使用了,于是第二次分配内存的时候再次将这块内存分配了出去
这里可以简单想象成一个单向链表的遍历,编译器在遍历过程中寻找可用的内存空间,并将第一个可用的内存空间分配出去 每次分配的时候遍历一次链表
这样可能会造成手动分配内存空间的速度更慢
int main (){
Node *b = new Node(232653,"kjk") ;
delete b ;
// Node * c = new Node(21312,"c") ;
b->print();
return 0 ;
}
如果我们不再给c分配内存空间 输出b 仍然会得到232653 说明delete之后堆内存空间中原有的数据并没有真正的清空 新的数据覆盖之后才会彻底消失
这里类似于硬盘的删除机制
之后笔者又在vs2015中测试了同样的代码 得到了不同的结果 vs是随机对堆内存进行分配的
以上仅为个人观点 如有不同 欢迎指正