CPP Module 01


new & delete


c++은 세 가지 타입 메모리 할당을 가진다.

  1. 하나는 정적 메모리 할당으로 정적(static) 변수와 전역 변수에 대해 발생한다. 프로그램 실행 시 한 번 할당되며 프로그램 종료 시까지 지속된다.

  2. 두 번째는 자동 메모리 할당으로 함수의 매개 변수와 지역 변수에 대해 발생한다. 관련 블록을 입력할 때 할당되고 블록 종료 시 해제된다.

  3. 세 번째는 동적 메모리 할당이다.


3 번째 동적 메모리 할당은 1, 2번째 메모리 할당 방식이 자동으로 해제되는 것과 달리 수동으로 메모리를 해제해주어야 한다. 이러한 동적 메모리 할당은 고정 배열과 같이 스택에 할당되지 않고 영역에 할당된다.


할당 방법

단일 변수를 동적으로 할당하려면 new 키워드를 사용하면 된다.

new 연사나는 메모리를 사용하여 객체를 만든 다음, 할당된 메모리의 주소인 포인터를 반환한다.

따라서 역참조(*)를 통해 메모리에 접근할 수 있다.


ex)

new int;
int *ptr = new int;
*ptr = 7;
// 아래와 같이 쓸 수도 있다.
// int *ptr1 = new int(5);
// int *ptr2 = new int{7};

delete

동적으로 할당된 변수는 그것을 가리키고 있는 포인터를 delete함으로써 해제해줄 수 있다.


delete ptr;
ptr = 0; // 0 == NULL

댕글링 포인터(Dangling Pointer)


delete해준 포인터는 무언가를 가리키게 설정하지 않으면 댕글링 포인터라는 것이 된다. 바꿔 말해 댕글링 포인터는 할당이 해제된 포인터인 것이다.

예를 통해 한번 살펴보자.


int main() {
  int *ptr = new int;
  int *otherPtr = ptr;

  delete ptr; // ptr과 otherptr 모두 댕글링 포인터가 됨.
  ptr = 0; // ptr은 이제 null이고 otherPtr만 댕글링 포인터.

  return (0);
}


time

Syntax & Header

#include <time.h>

time_t time(time_t *t);

time()함수는 1970-01-01 00:00:00 +0000 (UTC) 이후부터 현재까지 경과된 초단위 값을 return한다.

t가 NULL이면 경과된 초단위의 값만 return한다.

만약 t가 NULL이 아니면 t에 결과값을 채우고 그 값을 return한다.


초 단위로 발생하는 랜덤 함수이기 때문에 주로 rand() 함수와 같이 사용한다.


rand & srand

header & syntax

# include <iostream>

srand(time(NULL));
std::cout << rand() << endl;

description

rand함수는 미리 저장되어 있는 난수표에서 seed값에 따라 난수를 뽑아온다.

이 때, rand()는 미리 저장된 결과를 보여줄 뿐이므로 실행할 때마다 그 값이 똑같다.

그래서 우리는 srand()를 통해 새로운 seed를 설정해주는데,

srand()에게 매초마다 새로운 정보를 주기 위해 time(NULL)을 사용해주는 것이다.


rand % n

rand() 함수는 0에서 32767의 값을 반환한다.

그런데 만약 우리가 필요한 수가 0~9라면 어떻게 해주면 될까?

다음과 같이 해주면 된다: int random = rand() % 10

위와 같이 해주는 경우 0~9 범위에 해당하는 수 하나가 나오게 된다.


만약 09가 아닌 110을 해주고 싶다면 맨 뒤에 + 1만 붙여주면 끝.

참고로 #include <cstdlib.h>, <time.h>를 빼먹으면 실행은 되는데 랜덤하게 값이 안나오는 이상한 결과를 가져온다.


#include <iostream>
using namespace std;

int main()
{
  cout << rand() << endl; // 41
  cout << rand() << endl; // 18467
  cout << rand() << endl; // 6334 -> 이들 값은 실행할 때마다 같음.
}

#include <iostream>
#include <time.h>
using namespace std;

int main()
{
  srand(time(NULL));
  cout << rand() << endl; 
  cout << rand() << endl;
  cout << rand() << endl;
    // 위 코드는 실행 값이 매번 다름.
  cout << rand() % 10 << endl; // 0~9까지 랜덤한 수가 나옴.
  cout << rand() % 10 + 1 << endl; // 1~10 중 랜덤 수 나옴.
}

Pointer vs Reference

Syntax

string str = "HI";

//pointer
string *p_str = &str;

//reference
string &ref_str = str;

cout << "Pointer:" << *p_str << endl;
cout << "Reference:" << ref_str << endl;

// 결과
// Pointer: HI
// Reference: HI

차이점

  1. pointer는 NULL을 가리킬 수 있지만 Reference는 NULL을 가리킬 수 없다.

    따라서 NULL을 가리킴으로써 발생하는 오류를 방지할 수 있다.(ex) segfault, NULL pointer execption)

    또한 매개변수로 사용할 때에도 NULL인 경우를 예외처리 하지 않아도 된다.

  2. 포인터는 변수의 주소를 할당하는 변수인 반면 레퍼런스는 값을 담는 공간이다. 그래서 포인터는 *이나 ->로 역참조를 해야 하지만 레퍼런스는 &만 빼고 그대로 쓰면 된다. 다만, 레퍼런스를 변경하면 그것의 값을 가지고 있는 공간의 값도 변하게 된다.


StringStream

공백을 구분자로 하나씩 string을 반환해준다.


예제와 헤더

<sstream>

#include <sstream>
#include <iostream>

using namespace std;

int main()
{
  // 값 할당법 1.
    stringstream ss1("42 seoul");
    string str1;

    while (ss1 >> str1)
    {
        cout << str1 << '\n';
    }

  // 값 할당법 2.
  string str2;
  string str3;
    stringstream ss2;
    ss2 << 42 << ' ' << "seoul";

    ss2 >> str2 >> str3;
    cout << str2 << "\n" << str3 << "\n";

    return (0);
}
/* 결과

42
seoul
42
seoul

*/

getline, ifstream, ofstream

ifstream

https://modoocode.com/236


ofstream

https://showmiso.tistory.com/12


get_line

https://hyeonstorage.tistory.com/306


refs -

https://boycoding.tistory.com/204

https://mrw0119.tistory.com/57

https://www.it-note.kr/134

'Code 42 > CPP MODULEs' 카테고리의 다른 글

CPP-Module-06  (0) 2021.02.04
Cpp Module 07, 08  (0) 2021.01.26
CPP Module 04, 05  (0) 2021.01.23
CPP module 02, 03  (0) 2021.01.21
Mac Os Valgrind 설치하기  (0) 2021.01.19
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기
// custom