2017-09-21 51 views
3

初始化我使用Visual Studio 2017年社區訪問衝突用memset

按照下面的討論後寫入到一個二維數組寫入錯誤:

Fastest way to zero out a 2d array in C?

我有一個2 d矩陣( 10×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; 
} 

任何幫助表示讚賞。

+2

'memset'要求填充的內存是一個連續的區域,但是你有11個單獨的分配。 –

+0

不要在C++中使用C語言問題的答案。他們是不同的語言;爲此使用'memset'既不必要也不是一個好主意。 –

+1

[正確分配多維數組](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Lundin

回答

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)); 

另外,如果你的陣列將永遠是10×10,你可以改爲聲明爲double cmatrix[10][10] :該內存是連續的,你可以做你的原始memset

+0

謝謝。是的,我可以驗證它是否適用於一維數組的memset。所以,對於一個2D數組,我將使用你的suggestioin。 – Tryer

+0

「您的二維數組實際上是一個數組數組,因此內存不連續」這是不正確的。它實際上是一個_pointers_數組。如果它是一個數組數組,內存_would_將會是連續的。 – Lundin

+0

@Lundin謝謝你的糾正,我會修復更具體的答案 – cbuchart

2

cmatrix是一個指針數組。 調用memset將其置零,實際上將所有指針設置爲0(這不是您想要的),這會導致稍後訪問衝突。 對於這種初始化的我會選擇選項2(一個在評論)

+0

從你的文章中,我明白,不能在二維數組上使用memset。是對的嗎?我很困惑,因爲https://stackoverflow.com/questions/2516096/fastest-way-to-zero-out-a-2d-array-in-c似乎表明,作爲一種有效的方式來初始化二維數組。 – Tryer

+1

@Tryer。它適用於二維數組,但不適用於那些動態分配的數組。嘗試與double cmatrix [10] [10]' –

+1

@Tryer相同,實際上該問題的OP提到了二維數組,而不是指針數組(儘管沒有顯示代碼),可能你的混淆來自那裏 – cbuchart

2

在此代碼:

double ** cmatrix = new double*[10]; 
for (int i = 0; i < 10; i++) 
    cmatrix[i] = new double[10]; 

你第一次分配的10個指針double數組( double*),然後,對於此陣列中的每個元素(指針),您將分配一個新的數組10 double s。

圖形:

​​3557188​​

不能調用memset零出這種數據結構,爲你分配內存,而不是memset一個呼叫需要連續內存。

可以做一個簡單的memset調用如果線性 2D陣列,即,分配的存儲器中存儲10 * 10 = 100 double秒的單個塊,具有new[]單個呼叫。

+0

感謝您的圖形描述。因此,[1] [0]不會跟隨[0] [9],而是像我一樣動態分配。如果cmatrix被聲明爲cmatrix [10] [10],那就沒問題了。是對的嗎? – Tryer

+1

@Tryer:是的,用'double cmatrix [10] [10]'你會得到一個連續的內存塊。 –