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。是的,这很糟糕,因为一旦函数第一次返回,静态指针将指向一个不再存在的对象。“存储东西的地方”是超出此回答范围的实现的详细信息。是否有一个在中声明为静态的变量