C++ C+中的指针在哪里+;存储在堆栈上还是堆中?

C++ C+中的指针在哪里+;存储在堆栈上还是堆中?,c++,pointers,memory-management,C++,Pointers,Memory Management,我试图理解堆栈和堆内存之间的区别,等等,并且在解释基本知识方面做得相当好 然而,在第二个解释中,我遇到了一个我有一个具体问题的例子,这个例子是: 有人解释说对象m是在堆上分配的,我只是想知道这是否是完整的故事。根据我的理解,对象本身确实是在堆上分配的,因为new关键字已用于其实例化 然而,指向对象m的指针不是同时分配在堆栈上吗?否则,对象本身(当然位于堆中)将如何访问。我觉得为了完整起见,本教程中应该提到这一点,忽略它会给我带来一些困惑,因此我希望有人能澄清这一点,并告诉我,我的理解是正确的,

我试图理解堆栈内存之间的区别,等等,并且在解释基本知识方面做得相当好

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

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

然而,指向对象
m
的指针不是同时分配在堆栈上吗?否则,对象本身(当然位于堆中)将如何访问。我觉得为了完整起见,本教程中应该提到这一点,忽略它会给我带来一些困惑,因此我希望有人能澄清这一点,并告诉我,我的理解是正确的,这个示例应该基本上有两个语句,必须说:

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


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

是的,指针在堆栈上分配,但指针指向的对象在堆上分配。你说得对

然而,指向对象m的指针不是在同一时间吗 在堆栈上分配

我想你指的是
成员
对象。指针分配在堆栈上,并将在函数的整个持续时间(或其作用域)内一直存在。之后,代码可能仍然有效:

#include <iostream>
using namespace std;

struct Object {
    int somedata;
};

Object** globalPtrToPtr; // This is into another area called 
                         // "data segment", could be heap or stack

void function() {
    Object* pointerOnTheStack = new Object;
    globalPtrToPtr = &pointerOnTheStack;
    cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
} // pointerOnTheStack is NO LONGER valid after the function exits

int main() {
     // This can give an access violation,
     // a different value after the pointer destruction
     // or even the same value as before, randomly - Undefined Behavior
    cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
    return 0;
}
#包括
使用名称空间std;
结构对象{
int-somedata;
};
对象**globalptrtroptr;//这是另一个叫做
//“数据段”,可以是堆或堆栈
空函数(){
Object*pointerOnTheStack=新对象;
GLOBALPTRTTOPTR=&pointerOnTheStack;

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

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

m
是指针。它位于堆栈上。可能您指的是指向
成员
对象的指针

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

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


通常,任何函数/方法本地对象和函数参数都是在堆栈上创建的。由于
m
是函数本地对象,因此它在堆栈上,但是
m
指向的对象在堆上。

在函数中声明变量时,它总是在堆栈上。因此,变量
成员*m
是在堆栈上创建。请注意,
m
本身只是一个指针;它不指向任何对象。您可以使用它指向堆栈或堆上的对象,也可以不指向任何对象

在类或结构中声明一个变量是不同的——这些变量位于类或结构实例化的任何地方

要在堆上创建内容,可以使用
new
std::malloc
(或其变体)。在您的示例中,您使用
new
在堆上创建一个对象,并将其地址分配给
m
。需要释放堆上的对象以避免内存泄漏。如果使用
new
分配,则需要使用
delete
;如果使用
std::malloc
分配,则需要使用
std::free
这种方法通常是使用“智能指针”,它是一个保存指针并具有释放指针的析构函数的对象。

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

C++具有以下存储类

  • 静止的
  • 自动的
  • 动态的
  • 线
大致上,dynamic对应于“heap”,automatic对应于“stack”

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

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 
}

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

是的,您的理解是正确的。指针在堆栈上分配,它指向的对象在堆上分配。指针是一个对象。对象的位置通常取决于其生存期;具有静态生存期的对象是位于全局内存中、堆上具有动态生存期的对象、堆栈上具有自动生存期或临时性的对象、某些其他特殊位置的异常等。堆栈或堆之类的词只是约定——指定生存期的简单方法,而不是内存中的某个特定位置。+1主要用于以前的所有内容“继续你的问题")由于这个问题本身是一个真理,这些附加的细微差别在我看来更为重要。为什么指向自动对象的
静态指针不好?是因为当函数结束时自动对象将被释放,但静态指针将继续存在吗?另外,如果动态变量存储在堆上,而自动变量被存储在堆栈上,静态变量存储在哪里?这个答案确实帮助了我,谢谢。@JayS。是的,这很糟糕,因为一旦函数第一次返回,静态指针将指向一个不再存在的对象。“存储东西的地方”是超出此回答范围的实现的详细信息。是否有一个在中声明为静态的变量