使用 memset 初始化后写入二维数组时出现访问冲突写入错误
Access violation writing error on writing to a 2D array after initializing using memset
我正在使用 Visual Studio 社区 2017。
以下讨论:
Fastest way to zero out a 2d array in C?
我有一个使用 memset
初始化的二维矩阵 (10 x 10)。这是选项 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;
}
感谢任何帮助。
使用 memset
您将覆盖内存分配返回的指针,因此当您稍后访问内存时,您实际上是在推迟一个空指针。
你的二维数组实际上是一个指针数组,所以内存不是连续的,你不能做一个memset
将它设置为0。从技术上讲,它只是一个指针,你动态分配space另外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
.
cmatrix
是一个指针数组。
将 memset
调用为零,实际上会将所有指针设置为 0(这不是您想要的),这会导致稍后的访问冲突。
对于这种初始化,我会选择选项 2(评论中的那个)
在此代码中:
double ** cmatrix = new double*[10];
for (int i = 0; i < 10; i++)
cmatrix[i] = new double[10];
你首先分配一个包含 10 个 指针的数组 给 double
(double*
),然后, 为每个 元素(指针)在这个数组中,你分配一个 new 数组 10 double
s.
图形化:
array of
double*
||
\/
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
| ... |
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
您不能调用 memset
将此数据结构清零,因为您分配了 分散的 内存,而对 memset
的单次调用需要 连续内存。
如果您 线性化 二维数组,您可以执行简单的 memset
调用,即分配单个内存块存储 10*10 = 100 double
s,一次调用 new[]
.
我正在使用 Visual Studio 社区 2017。
以下讨论:
Fastest way to zero out a 2d array in C?
我有一个使用 memset
初始化的二维矩阵 (10 x 10)。这是选项 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;
}
感谢任何帮助。
使用 memset
您将覆盖内存分配返回的指针,因此当您稍后访问内存时,您实际上是在推迟一个空指针。
你的二维数组实际上是一个指针数组,所以内存不是连续的,你不能做一个memset
将它设置为0。从技术上讲,它只是一个指针,你动态分配space另外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
.
cmatrix
是一个指针数组。
将 memset
调用为零,实际上会将所有指针设置为 0(这不是您想要的),这会导致稍后的访问冲突。
对于这种初始化,我会选择选项 2(评论中的那个)
在此代码中:
double ** cmatrix = new double*[10]; for (int i = 0; i < 10; i++) cmatrix[i] = new double[10];
你首先分配一个包含 10 个 指针的数组 给 double
(double*
),然后, 为每个 元素(指针)在这个数组中,你分配一个 new 数组 10 double
s.
图形化:
array of
double*
||
\/
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
| ... |
+------+
| x-----------> [0|1|... <10 doubles> ...|9]
+------+
您不能调用 memset
将此数据结构清零,因为您分配了 分散的 内存,而对 memset
的单次调用需要 连续内存。
如果您 线性化 二维数组,您可以执行简单的 memset
调用,即分配单个内存块存储 10*10 = 100 double
s,一次调用 new[]
.