Programing

작성자가 C ++에서 스택 및 힙을 설명하는 데 실수를 했습니까? 아니면 내가 뭔가를 잘못 읽었습니까?

crosscheck 2021. 1. 5. 08:29
반응형

작성자가 C ++에서 스택 및 힙을 설명하는 데 실수를 했습니까? 아니면 내가 뭔가를 잘못 읽었습니까?


다음은 코드입니다.

int main()
{
    using namespace std; 
    int nights = 1001; 
    int * pt = new int; // allocate space for an int
    *pt = 1001;         // store a value there

    cout << "nights value = ";
    cout << nights << ": location " << &nights << endl;
    cout << "int ";
    cout << "value = " << *pt << ": location = " << pt << endl;

    double * pd = new double; // allocate space for a double
    *pd = 10000001.0; // store a double there

    cout << "double ";
    cout << "value = " << *pd << ": location = " << pd << endl; 
    cout << "location of pointer pd: " << &pd << endl;
    cout << "size of pt = " << sizeof(pt);
    cout << ": size of *pt = " << sizeof(*pt) << endl;
    cout << "size of pd = " << sizeof pd;
    cout << ": size of *pd = " << sizeof(*pd) << endl;

    return 0;
}

이제 코드에 대한 작성자의 메모입니다.

주목해야 할 또 다른 점은 일반적으로 new 는 우리가 사용해온 일반적인 변수 정의와는 다른 메모리 블록을 사용한다는 것입니다. 변수 nightspd모두 스택 이라는 메모리 영역에 값을 저장하는 반면, new에 의해 할당 된 메모리 힙 또는 여유 저장소 라는 영역에 있습니다 .


초기 질문 :

이제 내 관심사는 이것입니다 : 변수 pd 는 키워드 new에 의해 생성 되었으므로 변수 pt 처럼 heap 이라는 영역에 저장되어야합니다. 둘 다 키워드 new에 의해 생성 되었기 때문 입니다.

여기에 뭔가 빠졌나요? 귀하의 의견에 대해 미리 감사드립니다.

보류에 따라 수정 된 질문 / 후속 조치 :

이 질문은 내가 무엇을 묻는 지 이해할 수 없었기 때문에 5 명이 보류했습니다 . 내 질문에 이미 답변이되었다고 생각하지만 내가 처음에 무엇을 물어 보았는지 아직 확실하지 않은 분들은 함께 읽어 주시기 바랍니다.

변수와 그 값이 메모리에 저장되는 위치에 대한 저자의 설명에 대해 명확하지 않았습니다. 저자의 설명까지는 new 키워드를 사용하여 동적으로 생성 된 메모리 (또는 컴파일 후 런타임 중에 말해야 함)가 스택이 아닌 힙에 저장 된다는 믿음이있었습니다 .

그래서 그가 pd 변수 스택에 저장된 값 이라고 썼을 때 혼란 스러웠지만 키워드 new를 사용하여 "런타임"동안 변수가 생성 되었다면 어떻게 가능 합니까? 그래서 그것은 힙에 있어야합니다 . 스택 .

위의 코드를 참조로 사용하고 특히 답변 의 ** 변수 (nights, pd 및 pt )를 사용하여 해당 코드의 관점에서 이해할 수 있도록하십시오.

미리 감사드립니다!


포인터 변수 pt와는 pd스택에 저장됩니다. 그들이 가리키는 값은 new로 할당되며 힙에 저장됩니다.

"호수"라고 표시된 화살표가있는 표지판을 쓴다고해서 표지판 자체가 호수라는 뜻도 아니고 호수에 설치해야한다는 뜻도 아닙니다. 오히려 호수 방향을 가리키는 단단한 바닥에 설치해야합니다.


저자가 저지른 유일한 실수는

  1. delete포인터 사용이 완료되면 호출하지 않습니다 .

  2. 의 반복 사용 endl은 의심 스럽다. \n대신 사용하십시오 .

  3. using namespace std;, 간결성을 얻기 위해 튜토리얼에서 자주 사용되는 반면 프로덕션 코드, 특히 헤더에서 잘못 권장됩니다.

  4. int * pt = new int; *pt = 1001;대신에 사용 int* pt = new int(1001);하는 것은 저자가 가지고있는 방식이 *pt두 문장 사이에 불필요하게 초기화되지 않은 상태 이기 때문에 의문의 여지가 있습니다 . 따라서 코드가 불안정성에 취약 해집니다.

  5. (미성년자). 할당이 실패 할 경우 예외를 throw 할 수 있는 가능성 에 대해 항상 생각 해야 합니다.newstd::bad_alloc

나는 스택 이라는 용어에 대해 너무 많이 걱정하지 않을 것이다 . 그것들은 언어 자체의 일부가 아닌 언어 구현 개념 입니다. 용어가 선호 자동 동적 저장 기간 . 이것이 C ++ 표준이 사용하는 것인데, 대체 용어를 많이 발명하는 이유는 무엇입니까?

정말 나는 책을 태워서 Stroustrup의 사본을 얻을 것입니다.


이제 내 관심사는 이것입니다. 변수 pd는 키워드 new에 의해 생성되었으므로 변수 pt와 마찬가지로 힙이라는 영역에 저장되어야합니다. 둘 다 키워드 new에 의해 생성 되었기 때문입니다.

아니, 그렇지 않았다. 코드는 다음과 같습니다.

 double * pd = new double; // allocate space for a double

이것은 다음과 다르지 않습니다.

double * pd;
pd = new double;

So clearly, pd itself is not created by the new operator, only the value it holds is. But he's talking about pd, not its value.


Pictures will help.

Automatic storage (stack)                      Dynamic storage (heap)
-------------------------                      ----------------------

Item        Address        Value               Address        Value
----        -------        -----               -------        -----          
nights      0xff001000     1001               
    pt      0xff001004     0x00b0fff0 ------>  0x00b0fff0     1001
    pd      0xff00100c     0x00b0fff4 ------>  0x00b0fff4     10000001.0            

The objects nights, pt, and pd all have auto storage duration. On most implementations, this means they are allocated from the runtime stack. The object nights lives at address 0xff0010001 and stores the value 1001. The object pt lives at address 0xff0010004 and stores the address of a dynamic object created by new, which is 0x00b0fff0. The object pd lives at address 0xff00100c and stores the address of another dynamic object created by new, which is 0x00b0fff4.

The heap objects at addresses 0x00b0fff0 and 0x00b0fff4 store the values 1001 and 10000001.0, respectively.

Edit

FWIW, I wrote a dumper utility some time ago that dumps out object addresses and contents; given the code

#include <cstdio>
#include "dumper.h"

using namespace std;

int main( void )
{
  int nights = 1001;
  int *pt = new int;
  *pt = 1001;
  double *pd = new double;
  *pd = 1000001.0;

  char *names[] = { "nights", "pt", "pd", "*pt", "*pd" };
  void *addrs[] = { &nights, &pt, &pd, pt, pd };
  size_t sizes[] = { sizeof nights, sizeof pt, sizeof pd, sizeof *pt, sizeof *pd };

  dumper( names, addrs, sizes, 5, stdout );

  return 0;
}

I get the output

       Item         Address   00   01   02   03
       ----         -------   --   --   --   --
     nights  0x7fff9efe7c6c   e9   03   00   00    ....

         pt  0x7fff9efe7c60   10   20   50   00    ..P.
             0x7fff9efe7c64   00   00   00   00    ....

         pd  0x7fff9efe7c58   30   20   50   00    0.P.
             0x7fff9efe7c5c   00   00   00   00    ....

        *pt        0x502010   e9   03   00   00    ....

        *pd        0x502030   00   00   00   00    ....
                   0x502034   82   84   2e   41    ...A

In this case, the addresses are real. On my system (x86_64/Linux SLES-10), stack addresses start high and grow "downwards" (towards lower addresses), while heap addresses start low and grow "upwards" (towards higher addresses).

x86 is little endian, meaning the addressed byte is the least significant byte; multi-byte objects need to be read from right to left.


  1. All addresses are made up out of thin air and are not meant to represent any real-world implementation or architecture.


The pd variable is stored in stack memory, however the memory location where pd points to is allocated in heap memory. I think author wanted to emphasize exactly this difference between these concepts.

ReferenceURL : https://stackoverflow.com/questions/44429933/did-the-author-make-a-mistake-in-explaining-stack-and-heap-in-c-or-am-i-misrea

반응형