询问关于带有原始缓冲区的特征库的一个问题

Ask about one issue regarding eigen library with raw buffer

本文关键字:问题 一个 特征 于带 原始 缓冲区      更新时间:2023-10-16

最近我正在使用特征库,我发现了这个关于原始缓冲区操作的问题。

在下面的代码中,我创建了两个9整数的原始缓冲区作为输入和输出。之后,我使用两个特征矩阵in/out,通过放置新的方法与特征映射来包装这两个缓冲区。然后我调用一个简单的转置运算。然而,调用转置操作的不同方式将导致完全不同的原始缓冲区结果。如果我直接调用特征转置函数,如代码1所示,结果是完全正确的,无论是结果矩阵和相应的原始缓冲区。但是,当我将转置操作包装在返回特征矩阵的自定义函数中时,如代码2所示,问题就出现了。事实证明,只有结果矩阵是好的,但原始缓冲区似乎是损坏的。有人知道这个问题吗?这是一个固有的bug吗?

<标题>代码1
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/Dense>
using Eigen::MatrixXi;                                                          

int main() {                                                                    
  int *in;                                                                      
  in = new int[9];                                                              
  for (int i = 0; i < 9; i++)                                                   
    in[i] = i;                                                                  
  int *out;                                                                     
  out = new int[9];                                                             
  for (int i = 0; i < 9; i++)                                                   
    out[i] = 0;                                                                 
  MatrixXi m_in;                                                                
  m_in.resize(3, 3);                                                            
  new (&m_in) Eigen::Map<MatrixXi>(in, 3, 3);                                   
  MatrixXi m_out;                                                               
  m_out.resize(3, 3);                                                           
  new (&m_out) Eigen::Map<MatrixXi>(out, 3, 3);                                 
  m_out = m_in.transpose();                                                     
  std::cout << m_out << std::endl;                                              
  std::cout << "------------" << std::endl;                                     
  for (int i = 0; i < 9; i++)                                                   
    std::cout << out[i] << std::endl;                                           
  return 0;                                                                     
}

代码1的结果:

0 1 2
3 4 5
6 7 8
------------
0
3
6
1
4
7
2
5
8
<标题>代码2 h1> P_4

您正在用另一个不同类型的对象覆盖一个对象。m_inEigen::Map<MatrixXi>(in, 3, 3)的内容覆盖,因为它是放置new的目标。m_in不是in缓冲区的所有者,以后的操作假设它是将破坏堆。

MatrixXi m_in;                                                                
m_in.resize(3, 3);                                                            
new (&m_in) Eigen::Map<MatrixXi>(in, 3, 3);   

将这3行(以及m_out的类似行)替换为:

Eigen::Map<MatrixXi> m_in(in, 3, 3);

这将不会从堆中分配任何额外的内存,而是利用先前分配的in[]out[]

另一个问题是in[]out[]没有被删除。这并不重要,因为程序无论如何都要退出,但是应该不鼓励有内存泄漏倾向的编程风格。