我正在使用2017年的Visual Studio社区。 p>
按照以下讨论:
Fastest way to zero out a 2d array in C?
我有一个2 D矩阵(10 x 10),我使用memset
进行初始化。这是选项1.
选项2使用两个for
循环初始化相同的矩阵,每个循环从0到9循环。
然后,当我写入有效的矩阵位置时,使用选项1时会引发访问冲突写入错误。使用选项2时,一切正常。
我复制的最小工作代码如下:
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
#include <math.h>
#include <cmath>
#include <vector>
#include <string>
#include <limits.h>
#include <stdlib.h>
#include <array>
int main(){
double ** cmatrix = new double*[10];
for (int i = 0; i < 10; i++)
cmatrix[i] = new double[10];
memset(cmatrix, 0, 10 * 10 * sizeof(double));//Option 1
//for (int i = 0; i < 10; i++)//Option 2
//for (int j = 0; j < 10; j++)
//cmatrix[i][j] = 0;
cmatrix[0][1] = 5;//This step produces error on Option 1, but not on option 2
return 0;
}
感谢任何帮助。
答案 0 :(得分:3)
使用memset
覆盖内存分配返回的指针,因此当您稍后访问内存时,实际上是推迟了空指针。
您的2D数组实际上是一个指针数组,因此内存不是连续的,您无法将memset
设置为0.从技术上讲,它只是一个指针并动态地为另外10个指针分配空间,他们每个都指向10个双打。
相反,使用双循环(嵌套fors)来初始化它,或者每行只使用一个memset
:
for (int i = 0; i < 10; ++i)
for (int j = 0; j < 10; ++j)
cmatrix[i][j] = 0.0;
// or
for (int i = 0; i < 10; ++i)
memset(cmatrix[i], 0, 10 * sizeof(double));
此外,如果您的数组总是10x10,则可以将其声明为double cmatrix[10][10]
:该内存是连续的,您可以执行原始memset
。
答案 1 :(得分:2)
cmatrix
是一个指针数组。
调用memset
为零,实际上将所有指针都设置为0(这不是你想要的),这会导致以后的访问冲突。
对于这种初始化,我会选择选项2(注释中的那个)
答案 2 :(得分:2)
在此代码中:
double ** cmatrix = new double*[10]; for (int i = 0; i < 10; i++) cmatrix[i] = new double[10];
首先将10个指针的数组分配给double
(double*
),然后将分配给每个元素(指针)数组,您分配一个10 double
的新数组。
图形:
array of
double*
||
\/
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
| ... |
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
您无法调用memset
将此数据结构清零,因为您分配了分散的内存,而只需调用memset
连续记忆。
如果你线性化 2D数组,你可以做一个简单的memset
调用,即分配一个存储10 * 10 = 100 double
s的单块内存,单次拨打new[]
。