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