ByteBuffer 클래스를 만들고 매소드 get, size 선언. private 맴버를 d, s를 두어 아래와같이 구현하였다.
#include <algorithm> ByteBuffer::ByteBuffer(char *data, int size) { if(size == 0) { d = nullptr; s = 0; } else if(data == nullptr) { d = new char[size]; s = size; } else { d = new char[size]; s = size; std::copy(data, data + size, d); } } ByteBuffer::~ByteBuffer() { delete[] d; } char *ByteBuffer::get() { return d; } int ByteBuffer::size() { return s; }
그리고 두개의 스레드에서 위 객체를 사용하는데… 몇시간 돌리다보면 자꾸 엑세스 오류가 발생하고 디버거 연결하여 실행하면 항상 저 객체에서 이미 free 된 메모리가 free된다고 브레이크 걸리거나 포인터가 NULL이여서 엑세스 오류가 발생했다. (객체를 생성할 때 size나 data나 값이 0이면 애초 객체를 생성하지 않도록하여 ByteBuffer::get()을 호출하면 0이 반환 될 일이 없다.)
참조카운트는 스레드 안전하다는데 그렇지않은 현상. 객체가 생성되고 콜백하는 코드는 아래와같았다.
callback(opaque, std::shared_ptr<ByteBuffer>(new ByteBuffer((char *)data, size)));
표준안에서는 shared_ptr의 객체 참조는 스레드 안전하다고는 되어있고… 실제 돌려보면 그렇지않고… 일단 구글링해보면 나오는 예제들은 아래와같은 형식을 띄고있었다.
std::shared_ptr<ByteBuffer> sharedData(new ByteBuffer((char *)data, size)); callback(opaque, sharedData);
당최 MSVC에서의 C++11은 제대로 구현되지않은것이 몇몇 있다고들었기에 그냥 MSVC의 stl로 위 형식으로 고치는 삽질은 패스하고 곧장 오래 전부터 shared_ptr이 구현되어있던 믿을만한 boost로 갈아타서 돌려보는 중.
boost::shared_ptr<ByteBuffer> sharedData(new ByteBuffer((char *)data, size)); callback(opaque, sharedData);
지금은 저렇게 고쳐서 돌려보고있는데… 만약 그래도 객체참조가 문제생기면 mutex를 쓰던 좀 더 삽질을 해봐야겠다.
P.S. 한시간 넘게 돌려보니 마찬가지 문제 발생. 로직을 다시 봐야겠다.