沿着这条线的讨论可以在
question和
here中找到,但我的情况略有不同,因为我正在处理动态分配的内存.
还请注意,memset不太适用于双倍价值.
无论如何,我试图使用std :: fill来填充动态分配的2D数组 –
#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)
Approtch 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 [0] [0])应该具有相同的含义,对吧?
方法4:我不确定这是否正确.
>我该怎么办?
> std :: fill是否为两个嵌套循环提供了额外的好处?
解决方法
与堆栈分配的2D阵列不同,动态2D阵列不能保证是连续的范围.然而,它是一个连续的指针范围,但是数组中的每个指针可能指向非连续的存储区域.换句话说,数据i 1的第一个元素可能不一定跟随数据i指向的数组的最后一个元素.如果你想知道为什么堆栈分配的2D数组是连续的,那是因为当你声明类似的东西时
double data[10][20];
然后编译器将其理解为10个(连续)元素的数组,每个元素的类型为double [20].后一种类型也是一个数组,它保证了连续的元素,因此双[20]元素(即20个双重一个接一个)在存储器中一个接一个地堆叠. double [10] [20]与double **有惊人的不同.
这就是std :: fill或std :: memset让你头疼的原因,因为它们都假设一个连续的范围.因此,在您的情况下,嵌套循环似乎是填充数组的最简单方法.
一般来说,使用一个“模拟”2D访问的一维数组要好得多,完全出于上述原因:数据局部性.数据位置意味着错过的缓存更少,整体性能更好.