기본 콘텐츠로 건너뛰기

라벨이 cpp인 게시물 표시

Java 람다함수에서 외부지역변수를 수정할 수 없는 이유

 C++ 하다 보면, 람다함수에서 외부지역변수 수정을 숨쉬듯이 하는 편인데, Java 에서 동일한 형태로 람다함수를 사용하려고 하면, 오류난다. // Java import java.util.function.Consumer; public class MyClass { public String getString() { String result = ""; Consumer<String> lamda = (String name) -> { result = "<<" + name + ">>"; }; return result; } public static void main(String[] args) { System.out.println("new MyClass().getString(): " + new MyClass().getString()); } } // 컴파일 결과 // javac MyClass.java // MyClass.java:8: error: local variables referenced from a lambda expression must be final or effectively final // result = "<<" + name + ">>"; // ^ // 1 error // C++ #include <iostream> #include <string> using namespace std; class MyClass { public: string getString() { string result; auto lamda = [&] (stri...

Google 서비스 계정 액세스토큰을 C/C++로 얻어내기

OAuth2에서 인증을 흔히 3단계 과정으로 얻어내는데, 이것을 "three-legged OAuth(줄여서 3LO)"라고 한다. 여기에서 반드시 사람이 OAuth를 제공하는 측 인증화면에 인증질을 하는게 보통이다. 그러나 서비스를 개발하면서 자동인증이 필요할 때가 있다. 서비스 감사 등의 부분에서 말이다. 이때 구글 OAuth2는 2LO를 지원한다. 단, 특수 계정이 필요하고, 지원 API가 한정적이다. (보안이슈 등) 참조:  Using OAuth 2.0 for Server to Server Applications 위 문서에서 다른 건 필요 없고, 개발 콘솔에서 <서비스 계정>을 생성하고, P12(PKCS#12) 파일을 다운로드 받아놓는 것에 주목하자. 문서에 보면 OAuth 주소 어찌고 저찌고... 요청응답 순서는 이렇지만, 그러지 말고 구글에서 미리 만들어놓은 클라이언트 라이브러리 가져다 써라 어쩌라 되어 있다. 좋다. 구글은 미리 예쁘게 Java, Python, PHP 등으로 클라이언트 라이브러리를 짜놨다. 하지만 C/C++은 없더라. 그래서 구글이 만들어놓은 PHP 클라이언트 라이브러리 소스 뜯어 보면서 액세스 토큰을 C/C++로 얻어내보았다. 사용라이브러리는 아래와 같다. OpenSSL >= 1.0.0 : http://openssl.org JsonCpp:  https://github.com/open-source-parsers/jsoncpp cURL:  http://curl.haxx.se 그러나 예제 소스에는 거의 의사코드 수준으로만... ㅋㅋㅋ Google OAuth2에 서비스 계정을 만드려면, JWT(Json Web Token, 발음 주의: 좃)이라는 포맷으로 요청을 해야한다. JWT 참조:  http://jwt.io/ (여기에서도 C/C++ 라이브러리는 찾아 볼 수가 없다) 영어 다시 해석하려면 어려우니까 미리 말을 남겨놔야겠다. ㅋㅋ...

기본 생성자가 없는 객체 배열을 만들 수 있나?

C++ in Action Book: Pointers There is no direct way to initialize the contents of a dynamically allocated array. We just have to iterate through the newly allocated array and set the values by hand. C++에서 new연산자를 이용해서 객체배열을 만들 때, 객체에 기본생성자는 없고 다른 생성자가 있을 경우는 사용할 수 있는 문법 자체가 전무하다. 그냥 처음부터 끝까지 돌면서 하나하나 초기화 해주시라는 답안이다. 잇힝~* C/C++이 상당히 유연하다고 생각했는데, 가끔씩 이런 것에서 뒷통수 때릴 수도 있다. 다른 언어는 어떨까? 왠지 Java/C#/D는 있을 것 같다. 원본 위치: http://purewell.egloos.com/4002582

Double free

각종 표준에는 이미 해체한 메모리를 다시 해체하려고 할 때 행동을 정의하지 않고 있으나, GLIBC는 깔끔하게 자살해주고 있다. 자살할 때 패턴을 눈에 익혀 놓으면 나중에 왜 죽었지?하는 일이 줄어들 것이다. #include <stdlib.h> int main(int argc, char* argv[]) { void* p(malloc(1024)); free(p); free(p); return 0; } 컴파일 및 실행 $ g++ -O2 -g dblfree.cpp -o dblfree $ ./dblfree *** glibc detected *** ./dblfree: double free or corruption (top): 0x000000001460a010 *** ======= Backtrace: ========= /lib64/libc.so.6[0x3704671684] /lib64/libc.so.6(cfree+0x8c)[0x3704674ccc] ./dblfree(__gxx_personality_v0+0x10e)[0x4005de] /lib64/libc.so.6(__libc_start_main+0xf4)[0x370461d8b4] ./dblfree(__gxx_personality_v0+0x39)[0x400509] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 08:07 45776987 /home/purewell/tmp/dblfree 00600000-00601000 rw-p 00000000 08:07 45776987 /home/purewell/tmp/dblfree 1460a000-1462b000 rw-p 1460a000 00:00 0 3703600000-370361a000 r-xp 00000000 08:03 4845228 ...

delete this

[16] Freestore management, C++ FAQ Lite (내 맘대로 번역) [16.15] Is it legal (and moral) for a member function to say delete this? [16.15] 멤버함수에서 'delete this'가 올바른 구문인가? As long as you're careful, it's OK for an object to commit suicide (delete this). 주의 깊게 사용한다면, 객체가 자살하는 구문(delete this)은 괜찮다. Here's how I define "careful": 어떻게 "주의 깊게" 사용하냐면: You must be absolutely 100% positive sure that this object was allocated via new (not by new[], nor by placement new, nor a local object on the stack, nor a global, nor a member of another object; but by plain ordinary new). 이 객체는 new연산자(new[]도 아니고, new 오버라이딩도 아니고, 스택에 있는 지역 객체도 아니고, 전역 객체도 아니고, 다른 객체의 멤버변수도 아닌 순수 그 자체 new연산자 )로 만들어진다는 100% 확신이 있어야한다. You must be absolutely 100% positive sure that your member function will be the last member function invoked on this object. 'delete this'를 호출한 멤버함수는 이 객체에서 호출한 가장 마지막 멤버함수 라는 100% 확신이 있어야한다. You must be absolutely 100% positive sure that the rest of your ...

list::insert, list::erase

STL가 제공하는 list에 insert, erase는 각각 iterator를 반환한다. (형태에 따라 반환하지 않는 것도 있으니 주의) iterator insert(iterator pos, const T& x) : pos 앞쪽에 x를 넣고, x에 대한 iterator를 반환한다. iterator erase(iterator pos) : pos에 해당하는 아이템을 삭제하고, pos 다음 iterator를 반환한다. 예) #include <iostream> #include <list> #include <set> #include <algorithm> using namespace std; typedef list<int> list_int; typedef list_int::iterator list_itr; class print { public: ostream& m_os; print(ostream& os) : m_os(os) {} void operator() (int v) { m_os << v << ' '; } }; template<typename _T> ostream& dump(ostream& os, const _T& cont) { for_each(cont.begin(), cont.end(), print(os)); os << endl; return os; } list_int& init(list_int& cont) { cont.clear(); for ( int i(0); i < 10; i++ ) { cont.push_back(i); } return cont; } template<typename _IteratorType> void testInsert(_IteratorType ib, ...

virtual destructor in C++

소스 #include <iostream> using namespace std; #define SHOWFUN() do { cerr << __PRETTY_FUNCTION__ << endl; } while(false) class CParent1 { public: explicit CParent1() {SHOWFUN();} ~CParent1() {SHOWFUN();} virtual void doWhat(void) const {SHOWFUN();} }; class CChild1 : public CParent1 { public: explicit CChild1() {SHOWFUN();} ~CChild1() {SHOWFUN();} virtual void doWhat(void) const {SHOWFUN();} }; class CParent2 { public: explicit CParent2() {SHOWFUN();} virtual ~CParent2() {SHOWFUN();} virtual void doWhat(void) const {SHOWFUN();} }; class CChild2 : public CParent2 { public: explicit CChild2() {SHOWFUN();} virtual ~CChild2() {SHOWFUN();} virtual void doWhat(void) const {SHOWFUN();} }; class CChild3 : public CParent1 { public: explicit CChild3() {SHOWFUN();} virtual ~CChild3() {SHOWFUN();} virtual void doWhat(void) const {SHOWFUN();} }; class CChild4 : public CParent2 { public: explicit CChild4() {SHOWF...