C++中的指针存储在堆栈中还是堆中?

nbu*_*urk 22 c++ pointers memory-management

我试图理解堆栈内存之间的区别,这个问题在SO上以及这个解释做了很好的解释基础知识.

然而,在第二个解释中,我遇到了一个我有一个具体问题的例子,例子如下:

堆分配示例

据说这个对象m是在堆上分配的,我只是想知道这是不是完整的故事.根据我的理解,对象本身确实在堆上分配,因为new关键字已用于其实例化.

但是,指向对象的指针m是不是在堆栈上分配的同一时间?否则,如何访问对象本身,当然它位于堆中.我觉得为了完整起见,本教程中应该提到这一点,留下它会给我带来一些混乱,所以我希望有人能够清楚地告诉我,我对我的理解是对的应该基本上有两个陈述,不得不说:

1. m已经在堆栈上分配了一个指向对象的指针

2.对象m本身(因此它携带的数据以及对其方法的访问)已在堆上分配

Rak*_*kib 21

您的理解可能是正确的,但陈述是错误的:

m已在堆栈上分配指向对象的指针.

m 指针.它在堆栈上.也许你的意思指向一个Member对象.

对象m本身(它携带的数据以及对其方法的访问)已在堆上分配.

正确的是,指向的对象m是在堆上创建的

通常,在堆栈上创建任何函数/方法本地对象和函数参数.由于它m是一个函数本地对象,它位于堆栈上,但指向的对象m位于堆上.


M.M*_*M.M 14

"堆栈"和"堆"是通用编程术语.特别是,不需要通过堆栈或堆数据结构在内部管理存储.

C++具有以下存储类

  • 静态的
  • 自动
  • 动态
  • 线

粗略地,动态对应于"堆",而自动对应于"堆栈".

转到你的问题:可以在这四个存储类中的任何一个中创建指针; 和指向的对象也可以在任何这些存储类中.一些例子:

void func()
{
    int *p = new int;            // automatic pointer to dynamic object
    int q;                       // automatic object
    int *r = &q;                 // automatic pointer to automatic object
    static int *s = p;           // static pointer to dynamic object
    static int *s = r;           // static pointer to automatic object (bad idea)
    thread_local int **t = &s;   // thread pointer to static object 
}
Run Code Online (Sandbox Code Playgroud)

如果在函数内,则声明没有说明符的命名变量是自动的,否则是静态的.

  • @JayS。是的,这很糟糕,因为一旦函数第一次返回,静态指针将指向不再存在的对象。“东西存储在哪里”是超出本答案范围的实现细节 (2认同)

use*_*031 5

在函数中声明变量时,它总是在堆栈上.所以你的变量Member* m是在堆栈上创建的.注意,它本身m只是一个指针; 它没有任何意义.您可以使用它指向堆栈或堆上的对象,或者根本不指向任何对象.

在类或结构中声明变量是不同的 - 那些实例化类或结构的地方.

要在堆上创建内容,请使用newstd::malloc(或其变体).在您的示例中,您使用new并在其上分配其地址来在堆上创建对象m.需要释放堆上的对象以避免内存泄漏.如果分配使用new,则需要使用delete; 如果使用分配std::malloc,则需要使用std::free.更好的方法通常是使用"智能指针",它是一个包含指针的对象,并具有释放它的析构函数.

  • 正确的是,典型的基于堆栈的 C++ 实现不会在堆栈上存储静态数据。静态数据与全局变量一起存储在单独的内存区域中。因此,大多数程序至少有三个数据存储区域:堆栈、堆和全局变量。实际上,通常还有更多,但您可以暂时忽略它们。 (2认同)