2012-04-09 37 views
1

我初始化數組作爲Enumerable.Repeat有一些內存問題?

Double[][] myarr = Enumerable.Repeat(new double[12], 13).ToArray(); 

然後在一個循環我正在遞增值等

這會導致如myarr所有值[1] [0],myArr,該[2] [0] ,myarr [3] [0] ..... myarr [12] [0]增加1。

在使用一個for循環(0-12)我很喜歡初始化

myarr[i] = new double[12]; 

爲什麼會這樣這個問題不發生?

回答

5

其他解答已經解釋了這個問題。解決方法是在每次迭代中創建一個新的數組,例如

double[][] myarr = Enumerable.Range(0, 13) 
          .Select(ignored => new double[12]) 
          .ToArray(); 
1

數組是參考。在Repeat調用中,您創建一個數組並將其引用分配12次。在你的循環中,你創建了12個不同的數組。

2

使用new double[12]您正在創建對雙精度數組的引用,然後您重複12次引用,所以myarr [0..n]將引用一個內存區域。

您可以使用如下因素的方法來解決THW問題

static T[][] CreateArray<T>(int rows, int cols) 
{ 
    T[][] array = new T[rows][]; 
    for (int i = 0; i < array.GetLength(0); i++) 
     array[i] = new T[cols]; 

    return array; 
} 

或與調用動作的每一步定製重複方法:

public static IEnumerable<TResult> RepeatAction<TResult>(Action<TResult> elementAction, int count) 
{ 
    for (int i = 0; i < count; i++) 
    { 
     yield return elementAction(); 
    } 
    yield break; 
} 
usage 
RepeatAction(()=>new double[12], 12); 
2

這是因爲new double[12]在內存中創建一個數組對象 - Enumerable.Repeat只是簡單地爲您提供對該數組的多個引用。

+0

這樣的設施(對該數組的多重引用)有什麼用?它會給數組賦予錯誤的值。 – 2012-04-09 09:17:59

1

Repeat()基本上只是捕獲併產生相同的元素多次,所以你有多個引用到內存中的同一個對象實例。

這是怎麼Repeat()實現:

private static IEnumerable<TResult> RepeatIterator<TResult>(TResult element, int count) 
{ 
    for (int i = 0; i < count; i++) 
    { 
     yield return element; 
    } 
    yield break; 
} 
2

這是正常現象 - 陣列是一個referebce類型。您正在創建一個鋸齒陣列,即陣列數組。外部數組的所有元素引用相同的內部數組,即Repeat調用的第一個參數,所以內部數組中的更改將反映在索引處(因爲所有索引都指向同一個數組)。

+0

這種設施的用途是什麼(對該陣列的多重引用)?它會給數組賦予錯誤的值。 – 2012-04-09 09:20:08