C++笔记——动态内存分配

来源:互联网 发布:java的职业规划 编辑:程序博客网 时间:2024/06/06 03:22

new/delete【C++动态分配运算符,可以重载】、malloc/free【C语言动态分配函数,不能重载】需要配对使用。

new [] / delete [] 生成和释放对象数组。

#include <iostream>#include <stdlib.h>using namespace::std;class Test{public:    Test()        : m_val(0)    {        cout << "Test" << endl;    }    ~Test(){        cout << "~Test" << endl;    }private:    int m_val;};int main(){    {        Test a;    }    cout << "end of }" << endl;    Test* pVal = new Test();    delete pVal;    pVal = NULL;    int* p = (int *)malloc(sizeof(int));    free(p);    p = NULL;    Test* pArray = new Test[2]; // 调用两次构造函数    delete[] pArray;            // 调用两次析构函数    return 0;}

-----------------------------------------------------------------

Bss段存放没有初始化或者初始化为0的全局变量。

Data段存放初始化为非零的全局变量。

静态变量在第一次进入作用域时被初始化,以后不必再初始化。

静态成员变量在类之间共享数据,也是放在全局/静态数据区中。并且只有一份拷贝。

#include <iostream>#include <stdio.h>int i = 0;class A{public:    int val;    static int nCount;    A() {++nCount;}    ~A() {--nCount;}};int A::nCount = 0; // 初始化类的静态成员变量int main(){    A a;    A b;    printf("Number of A is %d ===>\n\n", A::nCount);    printf("no static variable: 0x%x\n", &a.val);    printf("no static variable: 0x%x\n", &b.val);    printf("static class member: 0x%x\n", &a.nCount);     printf("static class member: 0x%x\n", &b.nCount);    printf("global member: 0x%x\n", &i);    return 0;}


-----------------------------------------------------------------

rodata存放常量数据。

常量不一定挡在rodata中,有些立即数直接和指令编码在一起,放在text中。

字符串常量,编译器会去掉重复的字符串,保证只有一个副本。

字符串会被编译器自动放到rodata中,加const关键字修饰的全局变量也放在rodata中

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <cstring>int main(){    char* p = "Hello";    char* p2 = "Hello";    // 字符串常量,编译器会去掉重复的字符串,保证只有一个副本    printf("p指向地址 = %p\n", p);    printf("p2指向地址 = %p\n", p2);    if(p == p2)    {        printf("Smart complier, set the string in one place!\n");    }    char* p3 = (char*)malloc(12);    memset(p3, 0, 12);   // ACSII码是0表示空格    // 将s所指向的某一块内存中的前n个字节的内容全部设置为ch指定的ASCII值,    // 第一个值为指定的内存地址,块的大小由第三个参数指定,    // 这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。    printf("p3 = %s\n", p3);    printf("p3指向地址 = %p\n", p3);    strcpy(p3, p2);    printf("p3 = %s\n", p3);    p3[1] = 'x';    printf("p3 = %s\n", p3);    free(p3);    p3 = NULL;    // p[1] = 'x';  会出现段错误,常量字符串是不能修改的    return 0;}

栈中存储自动变量或局部变量,以及传递的参数等。

堆是用户程序控制的存储区,存储动态产生的数据。

当用malloc/new来申请一块内存或者创建一个对象时,申请的内存在堆上分配,需要记录得到的地址,并且在不需要的时候释放这些内存。

栈一般很小,满足不了程序逻辑的要求。

-----------------------------------------------------------------

#include <iostream>#include <stdio.h>class AA{public:    A() {printf("A created\n");}    ~A() {printf("A destroyed\n");}};class B{public:    B() {printf("B created\n");}    ~B() {printf("B destroyed\n");}};A globalA; // 调用A的构造函数B globalB; // 调用B的构造函数int foo(void){    printf("\nfoo()---------------->\n");    A localA; // 调用A的构造函数    static B localB; // 调用B的构造函数,因为localB是静态对象,不用再次调用构造函数    printf("foo()<-------------------\n");    return 0;  // 至此只调用A的析构函数,静态对象localB生命期未到。}int main(){    printf("main()------------------->\n");    foo();    foo();    printf("main()<-------------------\n");    return 0;    // 至此分别调用B和A的析构函数2次和1次}


作用域由{}定义,并不一定是整个函数。

------------------------------------------------------------------------------------------

#include <iostream>#include <stdio.h>class A{public:    A() {printf("A created\n");}    ~A() {printf("A destroyed\n");}    // 拷贝构造函数    A(const A& a) {printf("A created with a copy\n");}};A *foo(A a){    printf("\nfoo()---------------->\n");    A *p = new A();  // 调用A的构造函数    printf("foo()<-------------------\n");    return p;      // 调用A的析构函数(对应32行的拷贝构造函数)}A *boo(const A& a){    printf("\nboo()---------------->\n");    A *p = new A();  // 调用A的构造函数    printf("boo()<-------------------\n");    return p;}int main(){    printf("main()---------------->\n");    A a;  // 调用A的构造函数    A *p = foo(a); // 传递a的副本,调用A的拷贝构造函数    delete p;     // 调用A的析构函数(对应15行的构造函数)    p = NULL;    p = boo(a); // 传递a的引用    delete p;   // 调用A的析构函数(对应23行)    p = NULL;    printf("main()<----------------\n");    // // 调用A的析构函数(对应31行的构造函数)    return 0;}



#include <iostream>#include <stdio.h>class A{public:    A() {printf("A created\n");}    ~A() {printf("A destroyed\n");}};A *CreateA(void){    printf("\nCreateA()---------------->\n");    A *p = new A();  // 调用A的构造函数    printf("\nCreateA()<----------------\n");    return p;}int main(){    A *pA = new A(); // 调用A的构造函数    printf("pA = 0x%x\n", pA);    delete pA;       // 调用A的析构函数    pA = CreateA();    printf("pA = 0x%x\n", pA);    delete pA;       // 调用A的析构函数    return 0;}