为什么本征矩阵到C数组转换给垃圾值的前两个指标
Why is Eigen matrix to C array conversion giving garbage values for the first two indices?
我有一个特征矩阵要转换为C数组。我可以用下面的例子来重复这个问题。
#include <iostream>
#include <Eigen/Core>
int *test()
{
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
// just to check
arr(4)=3;
arr(5)=19;
return arr.data();
}
int main()
{
int *c_arr;
c_arr = test();
for (int i=0; i<6;++i)
{
std::cout << c_arr[i] << std::endl;
}
return 0;
}
输出:0
0
1
1
3
19
现在,如果我从test
函数中打印转换后的C数组值,则值是正确的。然而,如果我打印main
的值(如上所示),前两个索引总是垃圾。所以我想知道在函数调用中发生了什么?我已经尝试过不同的特征矩阵(类型,大小),我得到相同的结果。
我首先要说的是,我不是100%熟悉Eigen库(只是出于好奇下载了它来看看),它的文档有点缺乏,但你的问题是一个基本的C问题,可以通过几种方式补救。
首先,我们将解释在你的代码中是如何给出垃圾值的:
int *test()
{
/* create an auto scoped variable on the stack;
this variable is only "visible" to this function
and any references to it or it's underlying data
outside the scope of this function will result
in "undefined behaviour" */
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
arr(4)=3;
arr(5)=19;
/* arr.data() is defined as returning a pointer to the scalar underlying type (or
a C-style array in other words). Regardless of the type being returned, it is pointer based
and you are returning a pointer to a location in memory, not the actual data being held in
the memory. */
return arr.data();
} /* the variable arr is destroyed here since we left function scope and the return value (the pointer location)
is put in the return register and "program flow" is returned back to the main function where the pointer being
returned now points to "invalid" memory */
int main()
{
int *c_arr; // create a pointer type that can reference int types
c_arr = test(); // point it to the result of the test function (see notes above)
/* c_arr now points to a memory location returned from test, but since the
arr variable no longer exists here, when you go through and print the values pointed
to at those memory locations you will get what is at those locations and could be "anything"
except a valid reference to the original arr variable and it's underlying data. */
for (int i=0; i<6;++i)
{
std::cout << c_arr[i] << std::endl;
}
return 0;
}
这就是为什么要,至于如何解决这个问题有几种方法;一种是将返回数组作为变量传递给test
函数(例如void test(int*& val)
),然后您可以选择在测试函数中为变量分配新内存,或者假设用户已经这样做了,并且必须假设用户将在自己之后清理并调用delete[]
(不仅仅是delete
,因为您正在操作数据数组)。
但是这有很多需要注意的地方,需要知道要分配多少空间,并确保在分配完成后重新分配。我不确定为什么你特别需要一个C风格的数组,但因为你使用c++,它可能会更谨慎,如果你使用一些STL和容器函数可用来帮助你,例如:
#include <iostream>
#include <vector>
#include <Eigen/Core>
std::vector<int> test()
{
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
arr(4)=3;
arr(5)=19;
// we need the size so we know how big of a container to allocate
std::size_t sz = arr.innerSize() * arr.outerSize();
std::vector<int> ret(sz);
// get a temporary C array pointer so we can reference the data
int* tmp = arr.data();
// copy from tmp[0] to tmp[sz] and insert the data into the first element of ret
std::copy(tmp, tmp+sz, ret.begin());
// return the (copied) data
return ret;
}
int main()
{
std::vector<int> c_arr = test();
// c_arr now points to valid data it holds and can be iterated on
for (std::size_t i = 0; i < c_arr.size(); ++i) {
std::cout << c_arr[i] << std::endl;
}
// if you need a C-style array from here, you can easily copy the data
// from the vector to your C-array
return 0;
}
我研究了使用类的cast()
函数,但是不能完全弄清楚语法,使它比上面的方式复制它更少痛苦,因为看起来你必须调用cast
函数到不同的Eigen
类型,然后从那里再次强制转换,但知道有一个cast
函数和其他方法来获得MatrixX
类的底层数据,如果你需要访问它。
相关文章:
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将具有两个通道的垫子转换为矢量<int><矢量>?
- C++stoi:这两个重载都无法转换所有参数类型
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 如何将4位整数值转换为C 中两个单独的2位值
- 将两个uint8_t转换为int16_t的正确现代方法
- 使用转换运算符相互转换两个不同类的对象
- 如何在两个复数的总和中使用自动类型转换?(C++)
- 如何将递归函数(具有两个基本情况)转换为迭代函数
- 为什么转换涉及两个用户定义的转换功能/构造函数
- 如何将此代码转换为两个以上的数字(计算HCF)
- 从两个图像转换的OpenCV
- 防止在执行时将两个类中的两个对象转换为 bool:if(a!=b)
- 如何将两个_pd转换为一个_ps
- 将两个uint32_t转换为uint64_t,然后根据位模式而不是值变回双精度
- 在两个不动点表达之间转换
- 将浮点类型转换为两个短字节(高字节和低字节)
- 运算符== 的两个操作数的隐式转换
- 如何以相同的比例转换两个视觉上相似的图像
- 两个具有转换方法的类