Machineboy空

Object-Oriented Data Structures # WEEK02 : Stack memory & Pointers 본문

Computer/자료구조

Object-Oriented Data Structures # WEEK02 : Stack memory & Pointers

안녕도라 2024. 1. 31. 11:37

2.1 Stack Memory and Pointers

 

In C++, the programmer has control over the memory and lifecycle of every variable!

By default, variables live in stack memory.

 

A Variable

Every C++ variable has four things:

  • A name
  • A type
  • A value
  • A location in memory ( = memory address)
int primeNumber 7;	//memory address is unknown

 

we can explore where this is going to be stored based on how we created this variable.

 

 

A Variable's Memory Address

In C++, the & operator returns the memory address of variable.

 

address : hexademical (16) 

 

 

Stack Memroy

 

By default, every variable in C++ is placed in stack memory.

 

Stack memory is associated with the current function and the memory's lifecycle is tied to the function

  • When the function returns or ends the stack memory of that function is released
  • lifecycle of any variable created inside function is exactly as long as function

Stack memory always starts from high addresses and grows down:

 

skip a little bit of memory: overhead to call foo function and some c++ internal maintainance;

 

실행 순서에 따라 할당 주소가 작아지는 것을 알 수 있음

꼭 grow down 하는 것은 아니다.

 

Note that C++ compilers can transform or rearrange the compiled code for optimization. In that case, the addresses of the variables in the stack layout may not be as predicted in the lecture. In practice, this won't affect your C++ programming for most applications, unless you go into certain fields like computer security research. The concept of the stack growing downward is often true on many computer architectures (but not universally).

 

This is more literally noticeable if you are programming in low-level assembly language instead of C++. Even in C++, you'll often find that variables "grow down" within a stack frame (unless the compiler has optimized the memory layout), and even more predictably, stack frames "grow down" within the program's memory space (unless the compiler has optimized away a function call or has done some other transformation).

 

 

Pointer

make c++ powerful

 

A pointer is a variable that stores the memory address of the data.

  • simply put: pointers are a level of indirection from the data.
  • if we follow the pointer to where pointer is pointing to, we can get to memory that stores real value 

In C++, a pointer is defined by adding an * to the type of the variable

  • Integer pointer : int *p = #

 

Deference Operator (역참조)

 

Given a pointer, a level of indirection can be removed with the deference operator *

 

역참조 연산자로 그 값에 직접 도달 가능

int num = 7;
int * p = #
int value_in_num = *p;
*p = 42;
// num은 7에서 42로 바뀐다 // value_in_num은 7이 저장되어 있다

 

 

Depending on the compiler, this example may simply crash with a segfault instead of displaying 0. Things like this can happen when any example tries to demonstrate undefined behavior. If you avoid undefined behavior in your programming, you can avoid many inconsistencies between systems and compilers.

 

Even if the code does not crash, if you look at what assembly code was generated by the compiler in such cases, the exact way that the stack space gets reused or overwritten may not be easy to explain. The compiler can make small optimizations to how it uses stack space for function calls, or how it stores values in CPU registers. If you accidentally take advantage of undefined behavior in your code, the results can be very unpredictable.

 

In practice, you won't have to worry about this too much, as long as you avoid undefined behavior. Be sure to initialize variables and do not access addresses to invalid memory.

 

포인터를 제대로 다루는 법을 배우자.

 

다음 강은 포인터의 사용이 더 많은 heap 메모리