gpt4 book ai didi

c++11 使用 std::fill 填充二维动态分配数组

转载 作者:太空狗 更新时间:2023-10-29 19:43:19 29 4
gpt4 key购买 nike

可以在这个 question 中找到沿着这条线的讨论还有here ,但我的情况略有不同,因为我处理的是动态分配的内存。

另请注意,memset 不适用于 double 值。

无论如何,我正在尝试使用 std::fill 来填充动态分配的二维数组 --

#include <iostream>
#include <algorithm>

using std::cout ; using std::endl ;
using std::fill ;

int main()
{
double **data ;
int row = 10, col = 10 ;
data = new double*[row] ;
for(int i = 0 ; i < col ; i++)
data[i] = new double[col];

// fill(&(data[0][0]),
// &(data[0][0]) + (row * col * sizeof(double)), 1); // approach 1
// fill(&(data[0][0]), &(data[0][0]) + (row * col), 1); // approach 2
// fill(data, data + (row * col * sizeof(double)), 1); // approach 3
// fill(&(data[0][0]),
// &(data[0][0]) +
// ((row * sizeof(double*)) +
// (col * sizeof(double))), 1); // approach 4

for(int i = 0 ; i < row ; i++) {
for(int j = 0 ; j < col ; j++)
cout << data[i][j] << " " ;
cout << endl ;
}

for(int i = 0 ; i < row ; i++)
delete [] data[i] ;
delete [] data ;
}

方法 1: 据我了解,方法 1 应该是正确的代码,我从头开始 &(data[0][0]) 和数组的末尾应该位于 &(data[0][0]) + (row * col * sizeof(double)),但是当我运行时,我得到了这个错误,但是数组已填满 --

1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
*** Error in `./test': free(): invalid next size (fast): 0x0000000000da3070 ***
Aborted (core dumped)

方法 2: 然而,根据这个 post ,建议使用方法 2,但我不太理解这段代码,因为缺少 sizeof(double),我得到了这个输出 --

1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
*** Error in `./test': free(): invalid next size (fast): 0x0000000000bf5070 ***
Aborted (core dumped)

方法 3: 我不确定为什么不能编译,data&(data[0][0]) 应该意思是一样的吧?

方法 4:我不确定这是否正确。

  1. 我该怎么做?
  2. std::fill 是否比两个嵌套循环有任何额外的好处?

最佳答案

与堆栈分配的二维数组不同,动态二维数组不能保证是一个连续的范围。然而,它是一个连续的指针范围,但数组中的每个指针可能指向非连续的内存区域。换句话说,data + i + 1 的第一个元素不一定跟在 data + i 指向的数组的最后一个元素之后。如果您想知道为什么堆栈分配的二维数组是连续的,那是因为当您声明类似

double data[10][20];

然后编译器将其理解为包含 10 个(连续)元素的数组,每个元素的类型为 double[20]。后一种也是数组,保证元素连续,所以double[20]元素(即20个double一个接一个)依次堆叠在内存。 double[10][20]double** 截然不同。

这就是为什么 std::fillstd::memset 让你头疼的原因,因为它们都假定一个连续的范围。因此,在您的情况下,嵌套循环似乎是填充数组的最简单方法。

一般来说,使用“模仿”二维访问的一维数组要好得多,这正是出于上述原因:数据局部性。数据局部性意味着更少的缓存丢失和更好的整体性能。

关于c++11 使用 std::fill 填充二维动态分配数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34475816/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com