C++中的静态和动态内存分配

Static and dynamic memory allocation in C++

本问题已经有最佳答案,请猛点这里访问。

为什么下面的猜测是错误的?(一个软件工程公司的经理告诉我这几乎是正确的,但我不明白为什么,我也不能在互联网上搜索答案。)

1
int* ptr = new int;      // Sorry I mistyped before

我的主张:

  • 左边部分(ptr)是静态内存分配。
  • 右边部分(new int)是动态内存分配。
  • //新编辑时间:2015年1月1日17:39(UTC+08:00)我想的是,它向下(或向上)移动堆栈指针。为ptr腾出一个空间。找一个空位给一个new int。然后把这个new int的地址存储到ptr中。


    左边是一个int,右边是一个int *(指针)

    你想要:

    1
    int * ptr = new int;

    或者如果您想进行静态分配

    1
    int num; // = 5; Will initialize num to 5

    我想解释一些关于您的代码的事情。

    部分

    1
    new int

    被认为是"动态分配",但实际上它是在堆内存中分配的。

    宣告

    1
    int ptr

    不是"静态分配",而是"自动分配",因为它是在堆栈内存上分配的。请注意,堆比堆栈大得多(Windows中每个线程的默认堆栈大小为1MB)。因此,您将无法在堆栈上分配大型数组。另一方面,理论上堆有4GB的内存地址空间,尽管一个进程只有2GB可用,而且它也是一个虚拟内存,当然不是物理内存。

    现在,由于您只将ptr表示为整数类型(而不是指针),编译器将失败,因为您试图将内存地址分配给非指针类型。因此,您需要明确地告诉编译器这是您的意图,并通过将内存分配(仅为32位地址)强制转换为int来告诉编译器:

    1
    int ptr = (int)new int; //allocate an int on the heap and cast the address to an int value

    问题是,现在ptr将保存一个32位数字,它是堆中内存分配的起始地址。您现在不能对该ptr做太多的操作,因为编译器将其视为简单的整数而不是指针,因此为了对其进行有意义的操作(而不仅仅是将地址保存为整数值),您需要将其强制转换为指针,而不是使用它。例如,用某个值初始化地址(假设值为5):

    1
    (*(int*)ptr) = 5; //cast to pointer and dereference it.

    如你所见,语法现在变得"丑陋",很难阅读/理解。如果你以"正确"的方式做事,你只需要这样写:

    1
    2
    3
    int* ptr = new int;

    *ptr = 5;  //dereference the pointer

    关于指针算术还有一件事:因为您的ptr只是一个整数而不是指针,所以当您递增它时:

    1
    2
    3
    int ptr = new int; //Assume ptr got the address 0x010
    ptr++;
    //Now ptr will hold the value of 0x011 because the value just got incremented by 1.

    但如果ptr是一个真正的指针:

    1
    2
    3
    4
    int* ptr = new ptr; //Assume ptr got the address 0x010
    ptr++;
    //Now ptr will hold the value of 0x014 because the size of an int is 4 bytes
    //and the pointer now points to the next address after the allocated integer.


    你的要求是正确的。

  • left part (ptr) is of static memory allocation.

  • right part (new int) is of dynamic memory allocation.

  • 换句话说,右部分返回一个int *,一个(动态分配的)指向int的指针。不能将它赋给int类型的(静态分配的)变量。


    因为您用无效的"int*"类型的右值初始化了"int"类型的变量。你应该把后者铸造成"尺寸T",然后它就可以工作了。

    1
    int ptr = (size_t)new int;

    在访问"ptr"的实际值之后,您应该写:

    1
    *(int*)ptr

    生活实例。