xcode对于堆内存的处理

3/8/2017来源:ASP.NET技巧人气:1632

在学习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是随机对堆内存进行分配的

以上仅为个人观点  如有不同 欢迎指正