我做了一个测试:首先,i有一个C func变量nums:nums,numCols和numDeps分别初始化为值3,5和2。这些变量表示3D数组的维数。内存分配:为指针数组分配内存对于每一行,内存被分配给一个指针数组(features[i])。对于2D数组中的每个元素,为双精度数组分配内存(features[i][j]). 3D数组中每个双精度的内存(features[i][j][k])用k的值初始化。打印:嵌套循环遍历3D数组中的每个元素。(features[i][j][k])使用%p格式说明符打印。返回结果:打印整个3D数组(特征)的地址。3D数组被转换为void* 并返回。
void*** data13feature() {
int numRows = 3; // Number of rows
int numCols = 5; // Number of columns
int numDeps = 2;
// Allocate memory for the array of pointers (rows)
double*** features = (double***)malloc(numRows * sizeof(double**));
// Allocate memory for each row (array of doubles)
for (int i = 0; i < numRows; ++i) {
features[i] = (double**)malloc(numCols * sizeof(double*));
for (int j = 0; j < numCols; ++j) {
features[i][j] = (double*)malloc(numDeps * sizeof(double));
for (int k = 0; k < numDeps; ++k) {
features[i][j][k] = k;
}
}
}
// Print the addresses of the array elements
for (int i = 0; i < numRows; ++i) {
for (int j = 0; j < numCols; ++j) {
for (int k = 0; k < numDeps; ++k) {
printf("%p ", (void*)&features[i][j][k]);
}
printf("\n");
}
printf("\n");
}
return (void***)features;
}
字符串
然后我使用cgo来运行func
func Data2featureWrapper4() {
result := C.data13feature()
typeOfMyVar := reflect.TypeOf(result)
fmt.Printf("typeOfMyVar: %v\n", typeOfMyVar)
fmt.Printf("%p\n", *result)
}
型
结果是
0x33289c0 0x33289c8
0x33289e0 0x33289e8
0x3328a00 0x3328a08
0x3328a20 0x3328a28
0x3328a40 0x3328a48
0x3328a90 0x3328a98
0x3328ab0 0x3328ab8
0x3328ad0 0x3328ad8
0x3328af0 0x3328af8
0x3328b10 0x3328b18
0x3328b60 0x3328b68
0x3328b80 0x3328b88
0x3328ba0 0x3328ba8
0x3328bc0 0x3328bc8
0x3328be0 0x3328be8
typeOfMyVar: **unsafe.Pointer
0x3328990
型
为什么功能的开始[0][0][0]不等于0x3328990
我测试了**void和 *void我发现它是相等的。哪里错了?3D指针的起始位置不应该是[0][0][0]元素的地址吗?如果我想用go反向解析这个3D数组,我应该怎么做?
1条答案
按热度按时间juzqafwq1#
问题是你只解引用了result一次,而你应该解引用它两次。我们可以通过查看我们正在比较的两个东西的类型来看到这是一个问题:
字符串
上面是一个
double*
。在go代码中,你有:型
这是一个
*unsafe.Pointer
(技术上是一个双指针,不安全。指针算作指针!)。如果你考虑你分配的结构,这是有意义的:[rows] => [rows] => [deps]
当你解引用一次结果时,你得到的是指向列数据的指针。如果你再解引用一次,你会得到你想要的,数组数据。
PS,一个更有效的方法来分配大块的内存,其中形状保持不变,是在一个大块中完成。我可以重写你的C代码如下:
型
现在,您还将注意到,数据在内存中是连续的,这使得它对缓存友好(特别是对于大数据量),并且只需要一个malloc/free。