Month: December 2013

Visual C++ 2010/2013의 linker bug

Visual c++ 2010, 2013에는 “unresolved external symbol” linking bug가 있다 -_-;; 그렇다, 2013에서도 사라지지 않은 문제이다.

다음과 같은 세 가지 케이스가 아니라면 & 어쩔 땐 되고 어쩔 땐 안 된다면 linking bug를 의심해보자.

1. Template class의 method definition을 .h가 아니라 .cpp에 넣어두었다. <= template class의 method definition은 .h에 있어야 한다. Visual c++에선 definition이 cpp에 있어도 가끔씩 링킹이 된다 -_-;

2. signature가 안 맞는다. 특히 function name의 오타자 / scope / “&” / const 위치 주의

 

아무리 해봐도 linking error가 풀리지 않는다면.. 내가 찾은 야매를 공개하자면 :

1. 해당 method가 정의된 .cpp 파일을 오른쪽 클릭한 뒤 “컴파일” 해 본다.

2. 솔루션 clear 한 다음 rebuild / build 해본다.

3. 이건 본인이 아주 즐겨쓰는 방법인데 ㅡㅡ; method가 정의된 cpp 파일에다 “using namespace std;”를 추가한다.

링킹 에러가 사라졌다가 다시 생긴다면 “using namespace std;”를 주석처리해본다.(…)

 

3번 방법은 특히 아주 짜세이다..

C++0x의 shared_ptr

C++은 garbage collection을 지원을 하지 않기 때문에 생성한 heap 객체를 언제 free해 줘야 할 지가 중요한 issue가 된다.(그런데 정말로 C++가 garbage collection을 지원하지 않나..?) 이는 ‘잘 쓰면’ 문제가 없지면 문제는 어떤 객체의 수명이 언제까지인지, 그리고 누가 들고 있는지를 고려하면서 프로그래밍을 하는 것은 때때론 지나치게 어렵다는 것이다..

JAVA에서 어떤 객체가 garbage collect될 조건은 바로 그 객체를 가리키는 reference가 하나도 없을떄이다. 그리고 gc는 주기적으로 이것을 체크한다. C++0x에도 이와 똑같은 방식으로 heap memory를 계속 해재해 줄 수 있도록 std::shared_ptr<T>를 지원한다.(원래는 boost library에 있었다 한다)

1. 사용법

#include<memory>
#include<iostream>
using namespace std;

class A{
public:
	int x;
};

int main(){
	shared_ptr<int> p1(new int(4));
	shared_ptr<int> p2(p1); // reference count를 1 늘린다.
	shared_ptr<int> p3(new int(4));
	shared_ptr<A> p2(new A());

	(*p2).x = 123;
	cout << "p1 == p2 : " << (p1 == p2) << endl; // result : 1
	cout << "p1 == p3 : " << (p1 == p3) << endl; // result : 0 ; == is pointer-equivalence
	cout << "*p1 == *p3 : " << (*p1 == *p3) << endl; // result : 1
	cout << "p2->x : " << p2->x << endl;
	return 0;
}

원래 pointer T*가  있을 자리에 shared_ptr<T>를 다 넣기만 하면 된다 ㅇㅇ

STL container도 다 쓸 수 있는데(set, map, vector..) 이유는 comparator가 잘 정의가 되어 있기 때문이다. == 연산자는 ‘주소가 같은가?’를 비교하고 <, > 연산자는 주소값을 비교한다.(shared_ptr<T>간의 비교는 T의 comparator<를 부르지 않는다!!) (http://en.cppreference.com/w/cpp/memory/shared_ptr/operator_cmp)

위 코드에서 memory leak은 없다. 이유는 shared_ptr이 reference count를 체크하면서 자기가 빠졌을 때 count가 0인 애들에 대해 저절로 free를 다 해주기 때문이다.

2. 주의할 점

다음과 같은 코드는 망한다

#include<memory>
#include<iostream>
using namespace std;

int main(){
	int p = new int(4);
	{
		shared_ptr<int> p1(p);
		cout << *p1 << endl;
	}
	*p = 123;
	cout << *p << endl;
	return 0;
}

아래도 망한다. 이 때는 weak_ptr을 써야 한다고 하는데 어떻게 하는지는 찾아봐야 할 듯 하다

#include<memory>
using namespace std;

class Faulty{
public:
	shared_ptr<Faulty> toSharedPtr()
	{ return shared_ptr<Faulty>(this); }
};

3. 그 외

Thread-safe하다고 한다. 어떤 개체에 대해 여러 개의 shared_ptr<T>를 실시간으로 여러 개 생성하고 파괴해도 안전하다. 단, 인자를 &로 전달했을 경우엔 nonsafe할 수 있다고 한다.

shared_ptr<T> 간의 복사는 약간의 copy load가 있다고 한다.

shared_ptr<T>간의 static_cast, dynamic_cast, const_cast는 static_pointer_cast(), dynamic_pointer_cast(), const_pointer_cast() 함수를 불러서 해결할 수 있다.(http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast)