프로그래밍 언어/C++
[C] 버퍼 오버플로 (buffer overflow)
프로그램이 데이터를 버퍼(buffer)에 저장할 때, 버퍼가 가득 차 넘치게 되어 프로그래머가 지정한 부분 바깥에 덮어 씌워버리는 취약점, 버그, 이를 이용한 공격 방법을 말한다. 넘쳐난 데이터는 원래 데이터를 밀어내거나 이상한 곳에 저장하는 것이 아니라 덮어 씌우는 것이다. 덮어 씌워진 메모리에는 다른 데이터가 이미 포함되어 있을 수 있고, 이 때문에 메모리 접근 오류, 프로그램 종료, 시스템 보안 취약점 등이 발생할 수 있다. 버퍼 오버플로는 보통 데이터를 저장하는 과정에서 그 데이터를 저장할 메모리 위치가 유효한지를 검사하지 않아 발생한다. 이러한 경우 데이터가 담긴 위치 근처에 있는 값이 손상되고 그 손상이 프로그램 실행에 영향을 미칠 수도 있다. 특히, 악의적인 공격으로 인해 프로그램에 취약점이..
[C++] 디버그 모드에서 변수의 메모리 차지 공간
int64의 크기는 8바이트이고 로컬변수 선언시 스택 메모리에 8바이트씩 차지하게 된다. 8바이트 크기의 변수 3개를 선언 후 메모리 주소를 확인해보자. int64 n1 = 1; int64 n2 = 2; int64 n3 = 3; cout
[C/C++] 메모리 오류에 대하여
1. C/C++에서 메모리 오류의 종류 일단 메모리 공간에 따라 크게 Heap Memory 에러와 Stack (local variables) Memory 에러가 있다. Heap 메모리 영역에서 발생가능한 에러는 이미 해제된 메모리 다시 해제 할때 할당된적도 없는 메모리 해제 할라고 할때 이미 해제된 메모리 영역에 뭔가 데이터를 쓰려고 할때 할당된 적이 없는 메모리에 뭔가 데이터를 쓰려고 할때 메모리 할당 에러 동적으로 할당된 메모리 배열에서 초과된 index의 위치를 읽거나 쓰려고 할때 1,2 번과 3,4번을 묶어서 볼 수 있는데 해제시에 발생하는 문제 vs 데이터 입력시 발생하는 문제로 볼 수 있다. 스택 메모리 영역에서 발생가능한 에러들로는 정적 배열에서 초과된 index의 위치를 읽거나 쓰려고 할때..
[골5] 27172 - 수 나누기 게임
#include #include #include #pragma region 빠른 입출력 #define FAST_IO() \ {\ ios::sync_with_stdio(false);\ cin.tie(NULL); \ cout.tie(NULL); \ }\ #pragma endregion using namespace std; #define MAX 1000001 int main() { FAST_IO(); int n; cin >> n; vector v(n); int scores[MAX]{ 0 }, cards[MAX]{ 0 }; for (int i = 0; i > v[i]; cards[v[i]] = 1; } // 에라토스테네스의 체 응용 for (int i = 0; i < n; i++)..
[C++] cout 소수점 n자리까지 표시하기
일반적으로 아무 설정 없이 소수점을 표시하면 #include using namespace std; int main(){ ios::sync_with_stdio(0); cin.tie(0); double x = 3.333333333; cout
[C/C++] 비트연산자 (&, |, ^, ~, <<, >>, and, or, xor, 비트 반전, 비트 이동)
1. & 연산자 & 연산은 두 개의 비트가 모두 1일 때 1을 반환하는 AND 연산을 한다. 따라서 & 연산자의 비트단위 연산의 결과는 다음과 같다. 위 연산의 결과 4의 비트는 다음과 같다. 00000000 00000000 00000000 00000100 즉 다음과 같은 연산과정을 거친다. 00000000 00000000 00000000 00001111 & 00000000 00000000 00000000 00010100 = 00000000 00000000 00000000 00000100 2. | 연산자 | 연산은 두 개의 비트 중 하나라도 1이면 1을 반환하는 OR 연산이다. 따라서 | 연산자의 비트단위 연산의 결과는 다음과 같다. 위 연산의 결과 31은 다음과 같은 연산과정을 거친다. 00000..
[C++] 함수를 객체로 사용하기 (std::function, std::mem_fn, std::bind)
Callable Callable 이란, 이름 그대로 호출(Call)할 수 있는 모든 것을 의미한다. 대표적인 예시로 함수가 있다. 하지만 C++에서는 ( ) 를 붙여 호출할 수 있는 모든 것은 Callable 이라고 정의한다. same_obj 는 클래스의 객체이지만, 함수처럼 ( ) 를 호출할 수 있다. 마찬가지로, a 는 람다 함수이지만, ( ) 를 통해 호출할 수 있기에 Callable 이라고 할 수 있다. #include struct S { void operator()(int a, int b) { std::cout
[C] 함수 포인터 사용법 & 예제 총 정리
함수의 주소 변수를 선언하면 메모리 공간이 할당되고 그 공간의 위치가 주소로 존재하듯이 함수를 선언해도 변수와 마찬가지로 메모리에 공간이 할당되며 그 위치를 표현하는 주소가 생겨난다. C언어 코드는 컴파일이 되면 기계어로 변경되고 프로그램이 실행되면 코드 세그먼트라는 메모리 영역에 위치하게 된다. 즉, 함수의 형태는 변경되겠지만 결국 메모리에 저장되기 때문에 주소를 가지게 된다는 의미다. #include void print_hello() { printf("Hello, world!\n"); } int main() { // 메모리 상에 저장된 함수의 주소값 printf("함수의 주소값 : %p\n", print_hello); // & 생략 가능 return 0; } 포인터 변수란? 위에서 설명했듯 포인터는 ..
[C++] 매크로 개념과 주의사항
매크로 -> 단순 치환 -> #define으로 정의한다. # : 전처리 지시자 -> 컴파일 이전에 수행 define : 정의하다. -> 컴파일 이전에 정의하라고 명령. #1 매크로 상수 #define 매크로이름 치환할 값 매크로 상수 사용 시 주의사항 -> 단순 치환이기 때문에 세미콜론을 작성할 경우 세미콜론까지 치환해버린다. 예) #define PI 3.14f; // 입력 cout 속도가 빠르다. -> 함수 호출을 위한 연산들이 필요 없어진다. 매크로 함수의 주의점 #1 연산을 수행할 때 연산자 우선순위를 명확하게 표시해야한다. 예) #define SQUARE(n) n * n cout
[실4] 28279 - 덱2
#include #include using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int n; cin >> n; deque dq; while(n--) { int o, t; cin >> o; if (o == 1) { cin >> t; dq.push_front(t); } else if (o == 2) { cin >> t; dq.push_back(t); } else if (o == 3) { if (dq.empty()) cout