在Stack上创建一个指针

时间:2013-05-25 13:19:03

标签: c++

我正在学习C ++,我对指针有疑问。

我有这段代码:

int* max = new int;
*max = 0;

我想,我在堆上创建了一个指针(如果我不对,请告诉我)。

一个问题:

有没有办法用一条指令创建一个初始化指针?(现在,我用两条指令)。

另一个问题:

如何在堆栈上创建指针?

我看到这样的代码:

int myVar = 20;
int* pVar = &myVar;

我认为我还没有在堆栈上创建指针,但我认为这是不在堆上创建指针的唯一方法。

我在C ++开发方面非常非常新。

5 个答案:

答案 0 :(得分:9)

指针是正常变量,其内容是内存地址。该内存可以是堆内存或堆栈内存。不要将指针与它指向的内存空间混淆。

你的第一个代码在堆上分配空间,它可以容纳一个int。您将指向存储器的指针存储在堆栈

你的第二个代码在堆栈上分配空间,它可以容纳一个int。您将指向存储器的指针存储在堆栈

所以两个指针都在堆栈上,但只有第二个指向堆栈

在这两种情况下,您分配的类型都是基本类型。默认情况下,初始类型不会初始化,除非您立即为其分配值(第二个代码),或使用构造函数语法,这也适用于堆分配的值:

int *max = new int(0);

顺便说一下,在第二个代码中可以使用相同的语法:

int myVar(20);

如果您感兴趣:您还可以在堆上定义指针。 int*是指向int的指针类型,所以请继续在堆上分配这样的类型:

new int*();

此表达式返回int**,然后您可以将其存储在某处。同样,您通常将此指针存储在堆栈中:

int **pointerToPointer = new int*();

int一样,您可以将new-expression中的int*初始化为某个指向int的指针(此处为上面的max指针):

int **pointerToPointer = new int*(max);

现在你有两个指针具有相同的地址:max(堆栈上的指针)和堆上的一些指针,你指向使用pointerToPointer,即跟随保持(我取消引用`pointerToPointer,它导致存储在该指针后面的值,这是一个指向int的指针):

max == *pointerToPointer

答案 1 :(得分:7)

int* max = new int;

上面的行在堆栈上创建一个指针,并使用存储在堆上的整数对其进行初始化。每当new涉及表达式时,它将返回指向其动态创建的操作数的指针:

根据C ++ 11标准的第5.3.4 / 2段:

  

new - 表达式创建的实体具有动态存储持续时间(3.7.4)。 [ - ] 如果实体是非数组对象,则new-expression返回指向所创建对象的指针。如果它是一个数组,new - 表达式返回一个指向数组初始元素的指针。

int myVar = 20;
int* pVar = &myVar;

在此示例中,指针及其值都存储在堆栈中。 new - 表达式没有参与赋值,因此在这种情况下堆上没有创建任何内容。

如果要在一行中初始化指向对象的值,则必须 value-initialize ,如下所示:

int* max = new int(5);

或在C ++ 11中,您可以使用统一初始化:

int* max = new int{5};

记住使用delete创建的new也很重要。由于内存处于动态分配状态,因此其生命周期不依赖于其创建范围。如果您忘记delete您的程序将导致内存泄漏。

delete max;

如果max是指向由new - 表达式创建的数组的指针,则使用delete[]

delete[] max;

注意:如果指针new - 表达式初始化,则无需删除。

通常建议您使用容器为您管理内存。像std::unique_ptr这样的东西会做。一旦调用了析构函数,就会删除它所拥有的内存:

std::unique_ptr<int> max{new int{5}};

在C ++ 14中,我们有make_unique

auto max = std::make_unique<int>(5);

答案 2 :(得分:2)

有没有办法用一条指令创建一个初始化指针?

是:

int * a = new int(20); //initialized with 20;

如何在堆栈上创建指针?

int myVar = 20;
int* pVar = &myVar;    //copied your code snipped It's alright

答案 3 :(得分:1)

你的第一个例子

int* max = new int;
*max = 0;

确实在堆上创建了一个新的int,而你的变量max保存了一个指向该int的指针。如果您打算使用它,那么当您不再需要它时,您将不得不使用delete max;来避免内存泄漏。

第二个例子

int myVar = 20;
int* pVar = &myVar;

在堆栈上创建一个int,pVar现在是一个指向int保存在内存中的地址的指针。但是,如果您使用此功能,则不必删除pVar,因为它不在堆上(您没有使用new关键字)。

两个变量(在堆和堆栈上创建)之间的主要区别在于堆栈变量在离开作用域时会自动删除。范围由花括号{}

定义
int* somefnc()
{
    int e1

    {
        int* e2 = new int(0);
        int e3 = 0;
    } // int e3 gets automatically deleted here

    return e2;
} // e1 gets automatically deleted here

// e2 still exists and has to be manually deleted.

指针的一个优点是处理数组时。如果要在堆栈上创建x元素的char数组,则必须在编译时知道元素的数量。如果要在运行时使用动态数量的元素创建x元素的char数组,则必须使用char* ar = new char[x];,然后通过ar[x-1] = '\n';访问它。


为了在堆上创建变量时初始化变量,您可以使用var x = new var(args);

答案 4 :(得分:0)

您可以将值作为参数传递给初始化堆中的内存。

 int *iptr = new int(20);

初始化值为20;

stack:包含局部变量。因此,当您创建指针并为其指定本地对象时。它指向堆栈中的变量。我们不是在堆上创建指针