CPP Module 01
new & delete
c++은 세 가지 타입 메모리 할당을 가진다.
하나는
정적 메모리 할당
으로 정적(static) 변수와 전역 변수에 대해 발생한다. 프로그램 실행 시 한 번 할당되며 프로그램 종료 시까지 지속된다.두 번째는
자동 메모리 할당
으로 함수의 매개 변수와 지역 변수에 대해 발생한다. 관련 블록을 입력할 때 할당되고 블록 종료 시 해제된다.세 번째는
동적 메모리 할당
이다.
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
차이점
pointer는 NULL을 가리킬 수 있지만 Reference는 NULL을 가리킬 수 없다.
따라서 NULL을 가리킴으로써 발생하는 오류를 방지할 수 있다.(ex) segfault, NULL pointer execption)
또한 매개변수로 사용할 때에도 NULL인 경우를 예외처리 하지 않아도 된다.
포인터는 변수의 주소를 할당하는 변수인 반면 레퍼런스는 값을 담는 공간이다. 그래서 포인터는
*
이나->
로 역참조를 해야 하지만 레퍼런스는&
만 빼고 그대로 쓰면 된다. 다만, 레퍼런스를 변경하면 그것의 값을 가지고 있는 공간의 값도 변하게 된다.
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
ofstream
https://showmiso.tistory.com/12
get_line
https://hyeonstorage.tistory.com/306
refs -
https://boycoding.tistory.com/204
'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 |
최근댓글