Skip to content

Commit

Permalink
fixed segfault due to double delete when copy-constructing fbow::Voca…
Browse files Browse the repository at this point in the history
…bulary (disregarded Rule of Three)

reenabled distance_hamming_32bytes
  • Loading branch information
Benedikt Führer committed Dec 11, 2018
1 parent 9a7d866 commit 1029eff
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 23 deletions.
22 changes: 7 additions & 15 deletions src/fbow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@

namespace fbow{


Vocabulary::~Vocabulary(){
if (_data!=nullptr) AlignedFree( _data);
}


void Vocabulary::setParams(int aligment, int k, int desc_type, int desc_size, int nblocks, std::string desc_name) {
auto ns= desc_name.size()<static_cast<size_t>(49)?desc_name.size():128;
desc_name.resize(ns);
Expand Down Expand Up @@ -48,8 +42,8 @@ void Vocabulary::setParams(int aligment, int k, int desc_type, int desc_size, in

//give memory
_params._total_size=_params._block_size_bytes_wp*_params._nblocks;
_data=(char*)AlignedAlloc(_params._aligment,_params._total_size);
memset( _data,0,_params._total_size);
_data = Data_ptr((char*)AlignedAlloc(_params._aligment, _params._total_size), &AlignedFree);
memset(_data.get(), 0, _params._total_size);

}

Expand Down Expand Up @@ -152,8 +146,7 @@ fBow Vocabulary::transform(const cv::Mat &features)

void Vocabulary::clear()
{
if (_data!=0) AlignedFree(_data);
_data=0;
_data.reset();
memset(&_params,0,sizeof(_params));
_params._desc_name_[0]='\0';
}
Expand All @@ -180,20 +173,19 @@ void Vocabulary::toStream(std::ostream &str)const{
str.write((char*)&sig,sizeof(sig));
//save string
str.write((char*)&_params,sizeof(params));
str.write(_data,_params._total_size);
str.write(_data.get(), _params._total_size);
}

void Vocabulary::fromStream(std::istream &str)
{
if (_data!=0) AlignedFree (_data);
uint64_t sig;
str.read((char*)&sig,sizeof(sig));
if (sig!=55824124) throw std::runtime_error("Vocabulary::fromStream invalid signature");
//read string
str.read((char*)&_params,sizeof(params));
_data=(char*)AlignedAlloc(_params._aligment,_params._total_size);
_data = Data_ptr((char*)AlignedAlloc(_params._aligment, _params._total_size), &AlignedFree);
if (_data==0) throw std::runtime_error("Vocabulary::fromStream Could not allocate data");
str.read(_data,_params._total_size);
str.read(_data.get(), _params._total_size);
}

double fBow::score (const fBow &v1,const fBow &v2){
Expand Down Expand Up @@ -262,7 +254,7 @@ uint64_t Vocabulary::hash()const{

uint64_t seed = 0;
for(uint64_t i=0;i<_params._total_size;i++)
seed^= _data[i] + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed^= _data.get()[i] + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
void fBow::toStream(std::ostream &str) const {
Expand Down
16 changes: 10 additions & 6 deletions src/fbow.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ struct FBOW_API fBow2:std::map<uint32_t,std::vector<uint32_t>> {
*/
class FBOW_API Vocabulary
{


static inline void * AlignedAlloc(int __alignment,int size){
assert(__alignment<256);

Expand All @@ -72,16 +70,22 @@ class FBOW_API Vocabulary
*(ptr-1)=(unsigned char)off; //save in prev, the offset to properly remove it
return ptr;
}

static inline void AlignedFree(void *ptr){
unsigned char *uptr=(unsigned char *)ptr;
unsigned char off= *(uptr-1);
uptr-=off;
std::free(uptr);
}

using Data_ptr = std::unique_ptr<char[], decltype(&AlignedFree)>;

friend class VocabularyCreator;

public:

~Vocabulary();
Vocabulary() = default;
Vocabulary(Vocabulary&&) = default;

//transform the features stored as rows in the returned BagOfWords
fBow transform(const cv::Mat &features);
Expand Down Expand Up @@ -125,7 +129,7 @@ class FBOW_API Vocabulary
uint32_t _m_k=0;//number of children per node
};
params _params;
char * _data=nullptr;//pointer to data
Data_ptr _data = Data_ptr(nullptr, &AlignedFree);//pointer to data

//structure represeting a information about node in a block
struct block_node_info{
Expand Down Expand Up @@ -190,9 +194,9 @@ class FBOW_API Vocabulary


//returns a block structure pointing at block b
inline Block getBlock(uint32_t b){assert( _data!=0);assert(b<_params._nblocks); return Block( _data+ b*_params._block_size_bytes_wp,_params._desc_size, _params._desc_size_bytes_wp,_params._feature_off_start, _params._child_off_start);}
inline Block getBlock(uint32_t b) { assert(_data != 0); assert(b < _params._nblocks); return Block(_data.get() + b * _params._block_size_bytes_wp, _params._desc_size, _params._desc_size_bytes_wp, _params._feature_off_start, _params._child_off_start); }
//given a block already create with getBlock, moves it to point to block b
inline void setBlock(uint32_t b,Block &block){ block._blockstart= _data+ b*_params._block_size_bytes_wp;}
inline void setBlock(uint32_t b, Block &block) { block._blockstart = _data.get() + b * _params._block_size_bytes_wp; }

//information about the cpu so that mmx,sse or avx extensions can be employed
std::shared_ptr<cpu> cpu_info;
Expand Down
5 changes: 3 additions & 2 deletions src/vocabulary_creator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ void VocabularyCreator::create(fbow::Vocabulary &Voc, const std::vector<cv::Mat>
if(!(_descType==CV_8UC1|| _descType==CV_32FC1))
throw std::runtime_error("Descriptors must be binary CV_8UC1 or float CV_32FC1");
if (_descType==CV_8UC1){
// if (_descNBytes==32)dist_func=distance_hamming_32bytes;
// else
if (_descNBytes==32)
dist_func=distance_hamming_32bytes;
else
dist_func=distance_hamming_generic;
}
else dist_func=distance_float_generic;
Expand Down

0 comments on commit 1029eff

Please sign in to comment.