작성자가 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 는 우리가 사용해온 일반적인 변수 정의와는 다른 메모리 블록을 사용한다는 것입니다. 변수 nights 와 pd 는 모두 스택 이라는 메모리 영역에 값을 저장하는 반면, new에 의해 할당 된 메모리 는 힙 또는 여유 저장소 라는 영역에 있습니다 .
초기 질문 :
이제 내 관심사는 이것입니다 : 변수 pd 는 키워드 new에 의해 생성 되었으므로 변수 pt 처럼 heap 이라는 영역에 저장되어야합니다. 둘 다 키워드 new에 의해 생성 되었기 때문 입니다.
여기에 뭔가 빠졌나요? 귀하의 의견에 대해 미리 감사드립니다.
보류에 따라 수정 된 질문 / 후속 조치 :
이 질문은 내가 무엇을 묻는 지 이해할 수 없었기 때문에 5 명이 보류했습니다 . 내 질문에 이미 답변이되었다고 생각하지만 내가 처음에 무엇을 물어 보았는지 아직 확실하지 않은 분들은 함께 읽어 주시기 바랍니다.
변수와 그 값이 메모리에 저장되는 위치에 대한 저자의 설명에 대해 명확하지 않았습니다. 저자의 설명까지는 new 키워드를 사용하여 동적으로 생성 된 메모리 (또는 컴파일 후 런타임 중에 말해야 함)가 스택이 아닌 힙에 저장 된다는 믿음이있었습니다 .
그래서 그가 pd 변수 가 스택에 저장된 값 이라고 썼을 때 혼란 스러웠지만 키워드 new를 사용하여 "런타임"동안 변수가 생성 되었다면 어떻게 가능 합니까? 그래서 그것은 힙에 있어야합니다 . 스택 .
위의 코드를 참조로 사용하고 특히 답변 의 ** 변수 (nights, pd 및 pt )를 사용하여 해당 코드의 관점에서 이해할 수 있도록하십시오.
미리 감사드립니다!
포인터 변수 pt
와는 pd
스택에 저장됩니다. 그들이 가리키는 값은 new로 할당되며 힙에 저장됩니다.
"호수"라고 표시된 화살표가있는 표지판을 쓴다고해서 표지판 자체가 호수라는 뜻도 아니고 호수에 설치해야한다는 뜻도 아닙니다. 오히려 호수 방향을 가리키는 단단한 바닥에 설치해야합니다.
저자가 저지른 유일한 실수는
delete
포인터 사용이 완료되면 호출하지 않습니다 .의 반복 사용
endl
은 의심 스럽다.\n
대신 사용하십시오 .using namespace std;
, 간결성을 얻기 위해 튜토리얼에서 자주 사용되는 반면 프로덕션 코드, 특히 헤더에서 잘못 권장됩니다.int * pt = new int; *pt = 1001;
대신에 사용int* pt = new int(1001);
하는 것은 저자가 가지고있는 방식이*pt
두 문장 사이에 불필요하게 초기화되지 않은 상태 이기 때문에 의문의 여지가 있습니다 . 따라서 코드가 불안정성에 취약 해집니다.(미성년자). 할당이 실패 할 경우 예외를 throw 할 수 있는 가능성 에 대해 항상 생각 해야 합니다.
new
std::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 0xff001000
1 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.
- 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
'Programing' 카테고리의 다른 글
angularjs의 다른 컨트롤러에서 함수를 호출하는 방법은 무엇입니까? (0) | 2021.01.05 |
---|---|
webpack angular2 앱의 node_modules에서 CSS를 가져 오는 방법 (0) | 2021.01.05 |
Ruby on Rails에서 프로그래밍 방식으로 네임 스페이스 / 모듈 이름을 어떻게 찾습니까? (0) | 2021.01.05 |
전체 프로젝트 또는 솔루션에서 사용하지 않는 네임 스페이스를 한 번에 제거 (0) | 2021.01.05 |
IIS 7.5 + RESTFul 서비스에 대해 PUT 및 DELETE 사용, 확장 없음 (0) | 2021.01.05 |