BLOG main image
분류 전체보기 (222)
Reversing (13)
Pwnable (4)
Linux Kernel (3)
Crypto (2)
Wargames (66)
Programming (18)
Write Up (32)
Project (22)
Web (2)
My Life (52)
Memo (3)
etc (2)
발표자료 (1)
36,064 Visitors up to today!
Today 13 hit, Yesterday 30 hit
daisy rss
tistory 티스토리 가입하기!
'Programming'에 해당되는 글 18건
2018.04.24 21:22
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <iterator>
#include <string>
 
int main(void)
{
  std::istreambuf_iterator<char> begin(std::cin), end;
  std::string s(beginend);
  std::cout << s;
 
  return 0;
}
cs


'Programming > C++' 카테고리의 다른 글

C++에서 문자열 EOF까지 입력받고 출력하기  (0) 2018.04.24
c++ 템플릿 공부  (0) 2017.08.29
Lvalue와 Rvalue  (0) 2017.05.20
Name
Password
Homepage
Secret
2017.08.29 14:16


두 값을 더하는 add연산을 하는 함수를 만들어야 한다는 상황을 가정해보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
 
/*
int add(int a, int b) {
    return a + b;
}
double add(double a, double b) {
    return a + b;
}
std::string add(std::string a, std::string b) {
    return a + b;
}
*/
 
template <typename T>
T add(T a, T b) {
    return a + b;
}
 
// 특수화 (Specialization)
template <typename T>
int add(int* a, int* b) {
    return *+ *b;
}
 
int main(void) {
    int a = 10, b = 20;
    double c = 10.4, d = 20.4;
    std::string s = "Hello", t = "World";
    int* pA = &a;
    int* pB = &b;
 
    int sum = add(a, b);
    double sum2 = add(c, d);
    std::string sum3 = add(s, t);
    int pSum = add<int*>(pA, pB);    // using specialization template
 
    std::cout << pSum << std::endl;
}
cs

템플릿이 없었다면 주석처럼 각 타입마다 모두 add함수를 만들어서 사용해야 할 것이다.
그런데 템플릿을 사용하면 이렇게 타입에 대해서 T로 표시하고 어찌어찌 해서 들어오는 타입대로 더할 수 있게 된다.
특정 자료형만 따로 정의할 일이 있으면 위에처럼 특수화를 해서 정의하면 된다.

그럼 int와 double은 어떻게 더해야 하는가? 
int + double은 double이지만 어떤 값이 double인지 알아내기는 쉽지 않다.
여러가지 대처 방법이 있을 수 있는데 가장 무난하고 권장되는 방법은

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
template <typename T1, typename T2>
auto add(T1 a, T2 b) -> decltype(a + b) {
    return a + b;
}
 
int main(void) {
    auto e = 10.4f;
    decltype(e) f = 24.5f;    // e의 타입으로 정의
 
    int a = 10;
    double b = 20.4;
 
    std::cout << add(a, b) << std::endl;
    std::cout << add(b, a) << std::endl;
}
cs

이렇게 auto로 반환하되 auto의 타입을 decltype을 이용해서 a + b의 타입으로 맞춰주면 된다.

다음은 가변인자에 대한 가변 템플릿이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
 
/*
int sum(int a, int b) {
    return a + b;
}
int sum(int a, int b, int c) {
    return a + b + c;
}
int sum(int a, int b, int c, int d) {
    return a + b + c + d;
}
int sum(int a, int b, int c, int d, int e) {
    return a + b + c + d + e;
}
// ...
*/
 
// C++11 : Variadic Template (가변 템플릿)
template <typename T, typename... Args>
T sum(T a, Args... args) {
    return a + sum(args...);
}
 
template <typename T>
T sum(T a) {
    return a;
}
 
int main(void) {
    int a = 1, b = 2, c = 3;
 
    std::cout << sum(a, b) << std::endl;
    std::cout << sum(a, b, c) << std::endl;
}
cs

가변 템플릿이 없었다면 주석에 있는 것처럼 모든 인자의 개수에 맞춰서 다 정의를 미리 해주어야한다.
그런데 가변 템플릿을 사용하면 그럴 필요가 없다.

가변 템플릿은 재귀적인 형태로 이루어지며 가변 인수를 받는 템플릿 함수와 재귀적으로 돌다가 인자가 하나만 남았을 때 처리하는 함수 총 두개가 필요하다.

가변 템플릿은 위에 처럼 쓰면 댄다.
그리고 저 가변 템플릿은 코드상에서는 재귀지만 컴파일 타임때 재귀는 모두 풀리고 그냥 함수로 풀려서 실제 컴파일 하면 재귀로 실행되지 않는다.
그래서 재귀함수의 오버헤드가 발생하지 않는다.

그럼 가변 템플릿과 이것 저것을 응용해서 

1
2
3
4
5
6
#include <iostream>
 
int main(void) {
    std::cout << 'a' << 3 << "String" << 3.14 << std::endl;
    PrintList('a'3"String"3.14);
}
cs

4번 라인과 5번 라인이 똑같이 나오도록 PrintList함수를 만들어보자.

물론 인자 개수와 타입은 각각 바뀔 수 있다.

알아서 만들자

'Programming > C++' 카테고리의 다른 글

C++에서 문자열 EOF까지 입력받고 출력하기  (0) 2018.04.24
c++ 템플릿 공부  (0) 2017.08.29
Lvalue와 Rvalue  (0) 2017.05.20
Name
Password
Homepage
Secret
2017.05.20 11:37


오늘 한거

1. Reference
2. C언어에서의 Lvalue와 Rvalue
3. C++에서의 Lvalue와 Rvalue
4. Rvalue Reference
5. 클래스를 생성할 때 기본으로 생성되는 것들 (6가지)

1. Reference

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
void swap(int&a, int&b) {
    int tmp = a;
    a = b;
    b = tmp;
}
 
int main(void) {
    int a = 10, b = 20;
    int& rA = a;
 
    cout << a << endl;
    cout << rA << endl;
    cout << &<< endl;
    cout << &rA << endl;
 
    swap(a, b);
 
    cout << "a : " << a << ", b : " << b << endl;
 
    return 0;
}
cs

이렇당. rA는 a와 같은 값을 가지고 있다. 그리고 주소를 출력해 보면 a와 rA의 주소가 같다. 닉네임 같은거다. 그래서 swap할 때 많이 쓰인당


2. C언어에서의 Lvalue와 Rvalue

C언어에서의 Lvalue와 Rvalue를 보자. int a = 10; 변수에 값을 대입하는 코드이다.
Lvalue는 위 구문에서 왼쪽과 오른쪽 모두 올 수 있는 값이다. 그리고 Rvalue는 오른쪽에만 올 수 있는 값이다. 10 = a; 이런거는 안된당ㅎㅎ 대체적으로 Lvalue는 변수, Rvalue는 상수를 의미한다.


3. C++에서의 Lvalue와 Rvalue

C++에서는 Lvalue Rvalue 구분을 해당 구문이 지난 후에 그 값이 남아있는가로 구분한다. 

'Programming > C++' 카테고리의 다른 글

C++에서 문자열 EOF까지 입력받고 출력하기  (0) 2018.04.24
c++ 템플릿 공부  (0) 2017.08.29
Lvalue와 Rvalue  (0) 2017.05.20
Name
Password
Homepage
Secret
2016.03.02 20:20


module_init(), module_exit() 매크로 사용

make


갑자기 커널 모듈로 리버싱 문제를 만들면 꽤 재밌을 것 같다는 생각을 하였다.. 모듈을 직접 분석하여 특정 주소에 키 값을 올리면 모듈이 체크하여 correct, wrong 구분하도록..

'Programming > Linux Kernel Module' 카테고리의 다른 글

Hello, World! 2  (0) 2016.03.02
Hello, World!  (0) 2016.03.02
Name
Password
Homepage
Secret
2016.03.02 11:20


Hello, World!를 로그에 기록하는 모듈을 만들어 보았다.


make


'Programming > Linux Kernel Module' 카테고리의 다른 글

Hello, World! 2  (0) 2016.03.02
Hello, World!  (0) 2016.03.02
Name
Password
Homepage
Secret
2016.01.10 20:40


파이프는 프로세스끼리의 통신(IPC)를 할 때 사용되는 방법 중 하나입니다. pipe()로 생성하는 파이프는 프로세스 내에 생성되는 것이 아닌 커널에 생성되며 파이프를 사용할 수 있는 파일 디스크립터만 프로세스에게 주어지게 됩니다. 그러므로 하나의 프로세스가 파이프를 생성하고, 그 파이프의 파일 디스크립터를 사용하여 프로세스간 통신을 할 수 있게 됩니다. 여기서 생성된 파이프에서 신경써야 할 것은 바로 파이프의 입출력 방향이 이미 결정되어 있다는 것입니다. 따라서 파이프를 생성하면 이를 이용할 수 있는 2개의 파일 디스크립터가 만들어지게 됩니다. 

pipe함수의 원형은 int pipe(int fd[2]) 입니다. 인자로 들어오는 두 개의 파일 디스크립터 중 fd[0]은 파이프의 읽기 전용 파일 디스크립터이고, fd[1]은 쓰기 전용 파일 디스크립터 입니다. 읽기 전용 파일 디스크립터로 쓰기를 할 수 없고 그 반대 역시 가능하지 않습니다. 여기서 통신을 하려면 서로 생성한 파일 디스크립터를 알아야 하기 때문에 부모 자식 관계의 프로세스에서만 사용할 수 있습니다. 완전히 다른 프로그램의 프로세스끼리 통신하려면 FIFO라는 것을 사용해야 합니다. 아래는 각 부모와 자식에게 메시지를 전송하는 예제입니다. 

이렇게 짜고 컴파일 하여 실행시켜 보면 

이렇게 서로 메시지를 주고 받는 것을 볼 수 있습니다.

'Programming > Linux' 카테고리의 다른 글

프로세스 끼리의 통신 - pipe()  (0) 2016.01.10
자식프로세스 생성 - fork()  (0) 2015.12.03
Name
Password
Homepage
Secret
2015.12.03 12:33


제가 공부한 내용을 정리한 내용이라 설명이 부실하고 혹은 올바르지 않은 부분도 있을 수 있습니다.


리눅스에서 fork함수를 사용하면 현재 프로세스의 자식 프로세스를 만들 수 있습니다. fork함수는 unistd.h라는 헤더에 선언되어 있습니다. 부모프로세스에서 fork함수를 호출하여 자식 프로세스를 만들면 자식 프로세스는 부모프로세스와 완벽히 똑같은 프로세스가 생성됩니다. 다만 하나, fork리턴 값이 0으로 설정된다는 차이점이 있습니다. 이 리턴값으로 부모인지 자식인지를 구분할 수 있습니다. 부모에서 fork를 호출하면 리턴값으로 자식의 pid가 리턴됩니다. 즉, 0이 리턴이 됐다면 자식 프로세스인 것이고 그 외의 값이 리턴됐다면 부모 프로세스 인 것입니다. 다만 -1이 리턴된다면 이는 자식 프로세스 생성에 실패했다는 것을 의미합니다.

예제를 하나 보겠습니다. 

부모 프로세스와 자식 프로세스에서 각각 카운트를 하는 프로그램입니다. 여기서는 깜빡 하고 리턴값이 -1일 때의 처리를 해 주지 않았는데 실제로 짤 때에는 꼭 해 주셔야 합니다. 이 소스를 실행시켜 보면 

이렇게 실행이 됩니다. 정상적으로 카운트를 잘 하고 있습니다. 두 프로세스는 독립적인 프로세스이기 때문에 각 카운트 값은 서로의 값에 전혀 영향을 끼치지 않습니다. 

이 두 프로세스간에 통신을 하려면 여러가지 방법이 있습니다. 나열해 보면 

Shared memory
Semaphores
Pipes
Signals
Memory-mapped files
Sockets

이렇게 있습니다. 여기서 주로 저는 pipe를 사용합니다. 


참고자료

http://forum.falinux.com/zbxe/index.php?document_srl=412814&mid=C_LIB
http://stackoverflow.com/questions/2849147/communicating-between-a-parent-and-its-children

'Programming > Linux' 카테고리의 다른 글

프로세스 끼리의 통신 - pipe()  (0) 2016.01.10
자식프로세스 생성 - fork()  (0) 2015.12.03
Name
Password
Homepage
Secret
2015.11.25 00:49


시스템 프로그래밍을 공부하는데 모르는 자료형이 너무 많았다. 그래서 MSDN에서 찾아 보았다. 

우선 링크는 

https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx 

여기이다. 진짜 처음 보는 자료형이 엄청 많이 있었다. 모르는게 생길 때마다 여기서 보면 될 것 같다. 몇 개만 정리해 놓아야 겠다. 


BOOL - 불런 타입의 변수로써 참과 거짓 두 값만 저장하는 자료형이다. WinDef.h에 선언되어 있다. (typedef int BOOL)

BYTE - 1바이트 짜리 자료형이다. WinNT.h에 선언되어 있다. (typedef unsigned char BYTE)

CALLBACK - 콜백 함수를 위한 콜링 컨벤션(함수 호출 규약)이다. WinDef.h.에 선언되어 있다. (#define CALLBACK __stdcall)

DWORD - 32비트 부호없는 정수형 자료형이다. 수의 범위는 0부터 4294967295까지 저장할 수 있다. IntSafe에 선언되어 있다. (typedef unsigned long DWORD)

HANDLE - 어떠한 객체의 핸들 값을 저장하는 자료형이다. WinNT.h에 선언되어 있다. (typedef PVOID HANDLE)

LPBOOL - BOOL 자료형의 포인터 자료형이다. WinDef.h에 선언되어 있다. (typedef BOOL far *LPBOOL)

※LP 또는 P가 앞에 접두어로 붙은 자료형은 모두 뒤에 있는 자료형의 포인터 자료형이다.

'Programming > Windows' 카테고리의 다른 글

Windows Data Types  (0) 2015.11.25
CreateThread  (0) 2015.10.20
Name
Password
Homepage
Secret
2015.10.22 00:32


AT&T문법 어셈블리 코딩 연습 - atoi


'Programming > Assembly' 카테고리의 다른 글

atoi 구현  (1) 2015.10.22
isnumber 구현  (0) 2015.10.21
isalpha 구현  (0) 2015.10.21
gets 구현  (0) 2015.10.21
strchr 구현  (0) 2015.10.20
Linux Syscall number  (0) 2015.10.20
와전프구맙소사 | 2017.05.06 16:57 신고 | PERMALINK | EDIT/DEL | REPLY
당신이 나를 구했습니다 나의천사여
Name
Password
Homepage
Secret
2015.10.21 21:11


AT&T문법 어셈블리 코딩 연습 - isnumber


'Programming > Assembly' 카테고리의 다른 글

atoi 구현  (1) 2015.10.22
isnumber 구현  (0) 2015.10.21
isalpha 구현  (0) 2015.10.21
gets 구현  (0) 2015.10.21
strchr 구현  (0) 2015.10.20
Linux Syscall number  (0) 2015.10.20
Name
Password
Homepage
Secret
prev"" #1 #2 next