指针地址的内存偶尔更改了函数前和后返回

Memory for pointer address sporadically altered pre and post function return

本文关键字:函数 返回 地址 内存 偶尔 指针      更新时间:2023-10-16

指定地址的内存在函数返回前后不相同,这种行为的基础尚不清楚。 多次调用该函数将偶尔产生正确的结果;然而,在巨大的时间里,记忆已经被改变了。

需要可靠地返回一个简单的 C/C++ 浮点数组(而不是 std::vector/array 等(

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
float* derive_inverse(float* wasm_memory_address, int size) {
MatrixXf matrix_from_memory = Map<Matrix<float, Dynamic, Dynamic, RowMajor> >(wasm_memory_address, size, size);
std::cout << 'n';
std::cout << "Matrix" << 'n';
std::cout << matrix_from_memory << 'n' << 'n';
MatrixXf inverse = matrix_from_memory.inverse();
std::cout << "Inverse" << 'n';
std::cout << inverse << 'n' << 'n';
float* vc = inverse.data();
std::cout << "inverse address prior to return: " << vc << 't' << 'n';
std::cout << "first few entries (column major order):" << 'n';
std::cout << vc[0] << 't' << vc[1] << 't' << vc[2] << 'n' << 'n';
return vc;
}
int main() {
float numbers[25] = { 1, 8, -9, 7, 5, 0, 1, 0, 4, 4, 0, 0, 1, 2, 5, 0, 0, 0, 1, -5, 0, 0, 0, 0, 1};
float* inverse = derive_inverse(&numbers[0], 5);
std::cout << "inverse address following return: " << inverse << 't' << 'n';
std::cout << "first few entries (column major order):" << 'n';
std::cout << inverse[0] << 't' << inverse[1] << 't' << inverse[2] << 'n' << 'n';
std::cout << "entire inverse matrix following return:" << 'n';
for (int col = 0; col < 5; col++) {
for (int row = 0; row < 5; row++) {
int index = row * 5 + col;
std::cout << inverse[row * 5 + col] << 't';
}
std::cout << 'n';
}
std::cout << 'n';
}

导致错误和正确结果的连续调用示例:

$ ./foo
Matrix
1  8 -9  7  5
0  1  0  4  4
0  0  1  2  5
0  0  0  1 -5
0  0  0  0  1
Inverse
1  -8   9   7  17
0   1   0  -4 -24
0   0   1  -2 -15
0   0   0   1   5
0   0   0   0   1
inverse address prior to return: 0x7ff5c8500ba0 
first few entries (column major order):
1   0   0
inverse address following return: 0x7ff5c8500ba0    
first few entries (column major order):
0   -3.68935e+19    0
entire inverse matrix following return:
0   -8  9   7   17  
-3.68935e+19    1   0   -4  -24 
0   0   1   -2  -15 
-3.68935e+19    0   0   1   5   
2.52234e-44 0   0   0   1   
$ ./foo
Matrix
1  8 -9  7  5
0  1  0  4  4
0  0  1  2  5
0  0  0  1 -5
0  0  0  0  1
Inverse
1  -8   9   7  17
0   1   0  -4 -24
0   0   1  -2 -15
0   0   0   1   5
0   0   0   0   1
inverse address prior to return: 0x7f96afd000a0 
first few entries (column major order):
1   0   0
inverse address following return: 0x7f96afd000a0    
first few entries (column major order):
1   0   0
entire inverse matrix following return:
1   -8  9   7   17  
0   1   0   -4  -24 
0   0   1   -2  -15 
0   0   0   1   5   
0   0   0   0   1

函数返回指向对象内部数据的指针,该对象在函数返回后不会存活。在调用函数中取消引用该指针会导致未定义的行为。

float* vc = inverse.data();   // inverse is not alive after the function returns.
...

return vc;  // The returned pointer becomes a dangling pointer once the function returns.

解决此问题的一种方法是返回对象而不是指向内部数据的指针。

MatrixXf derive_inverse(float* wasm_memory_address, int size) {
...
return inverse;
}