Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCV提取的描述符会导致valgrind在复制时报告无效读取_C++_Opencv_Memory Leaks_Valgrind - Fatal编程技术网

C++ OpenCV提取的描述符会导致valgrind在复制时报告无效读取

C++ OpenCV提取的描述符会导致valgrind在复制时报告无效读取,c++,opencv,memory-leaks,valgrind,C++,Opencv,Memory Leaks,Valgrind,我知道至少已经有十几个valgrind报告无效阅读问题,但请容忍我,因为我真的不知道如何帮助自己,所以我要问你的问题 我正在为OpenCV特性检测和特性描述模块编写一个包装器(我希望能够在某个时候实现我自己的专长检测/提取)。因此,我不能直接对OpenCV数据类型进行操作 因此,当从特征中提取描述符时,我将它们存储为std::vector,而不是cv::Mat。我有一段代码,首先计算描述符,然后将它们从一种符号转换为另一种符号: // private void CVDescriptor::cal

我知道至少已经有十几个
valgrind报告无效阅读
问题,但请容忍我,因为我真的不知道如何帮助自己,所以我要问你的问题

我正在为OpenCV特性检测和特性描述模块编写一个包装器(我希望能够在某个时候实现我自己的专长检测/提取)。因此,我不能直接对OpenCV数据类型进行操作

因此,当从特征中提取描述符时,我将它们存储为
std::vector
,而不是
cv::Mat
。我有一段代码,首先计算描述符,然后将它们从一种符号转换为另一种符号:

// private
void CVDescriptor::calculateDescriptors(std::vector <cv::KeyPoint> &feats){
    this->feats = &feats;
    this->descCalc->compute(*(this->image), feats, this->desc);
    this->calculated = true;  
}

// public
void CVDescriptor::calculateDescriptors
                         (std::vector< std::vector< double > >& desc,
                          std::vector< cv::KeyPoint >& feats){    

    if (!this->calculated)
        this->calculateDescriptors(feats);

    assert(this->calculated);

    const double *temp;
    desc.clear();
    desc.reserve(this->desc.rows);
    for (int i=0, szi = this->desc.rows; i < szi; ++i){
        temp = this->desc.ptr<double>(i);

        // this line is the problem
        desc.push_back(std::vector<double>(temp, temp+(this->desc.cols)));
        //  .
        // /|\
        //  |
    }

    assert(desc.size() == this->desc.rows);
    assert(desc[0].size() == this->desc.cols);
    return;
}
//私有
void CVDescriptor::calculateDescriptors(std::vector和feats){
此->专长=&feats;
此->描述->计算(*(此->图像),专长,此->描述);
此->计算=真;
}
//公开的
void CVDescriptor::calculateDescriptors
(标准::矢量<标准::矢量>&desc,
std::vector&专长){
如果(!此->已计算)
这->计算脚本(专长);
断言(此->已计算);
常数双*温度;
说明清除();
说明保留(此->说明行);
对于(inti=0,szi=this->desc.rows;i说明ptr(i);
//这条线就是问题所在
desc.push_back(std::vector(temp,temp+(this->desc.cols));
//  .
// /|\
//  |
}
断言(desc.size()==此->desc.rows);
断言(desc[0].size()==this->desc.cols);
返回;
}
以下是我的成员变量的类型,我在初始化它们的地方进行了检查和编写(只是为了避免混淆):

std::vector*专长
cv::Mat*图像;
//它是在调用calculateDescriptors(描述、专长)之前设置的
cv::Mat desc;
bool计算;//在唯一构造函数中设置
这是我的建议。从我所看到的,每个计算出的描述符应该是
cv::Mat
中的一行,并且应该具有与矩阵中的列一样多的组件


我怀疑我的代码中的某些地方存在内存泄漏,所以我通过Valgrind运行了它。它报告的第一件事是在我的代码摘录中用一个大箭头标记的行上
大小为1的无效读取。就我所见,它在每次调用
CVDescriptor::calculateDescriptors(..)
时只报告两次,而不是在
for循环的每次迭代中

有人能看到我的复制代码有什么明显的错误吗?或者有没有其他想法,这可能是怎么发生的


如果需要,我可以提供额外的信息,但我已经尝试将所有相关的代码放在这里(因为我的项目相当大)。提前谢谢大家(我很抱歉问了这么长的问题).

我添加了一份打印件,上面列出了每次迭代中复制的内存块的起始地址和结束地址,这就暴露了问题所在。摘录自打印输出:

copied from 0xc0d5990 -- 0xc0d5d90
copied from 0xc0d5b90 -- 0xc0d5f90
copied from 0xc0d5d90 -- 0xc0d6190
copied from 0xc0d5f90 -- 0xc0d6390
copied from 0xc0d6190 -- 0xc0d6590
在每次迭代中,我都不小心试图同时复制两行
cv::Mat
,因为我是通过
指针访问它的,而存储的数据是
浮点

temp
声明为
const float*temp和更改中的
temp
分配

temp = this->desc.ptr<float>(i);
temp=this->desc.ptr(i);

我在每次迭代中都添加了一个被复制内存块的起始地址和结束地址的打印输出,这就暴露了问题所在。摘录自打印输出:

copied from 0xc0d5990 -- 0xc0d5d90
copied from 0xc0d5b90 -- 0xc0d5f90
copied from 0xc0d5d90 -- 0xc0d6190
copied from 0xc0d5f90 -- 0xc0d6390
copied from 0xc0d6190 -- 0xc0d6590
在每次迭代中,我都不小心试图同时复制两行
cv::Mat
,因为我是通过
指针访问它的,而存储的数据是
浮点

temp
声明为
const float*temp和更改中的
temp
分配

temp = this->desc.ptr<float>(i);
temp=this->desc.ptr(i);
这就是诀窍