2012-04-09 22 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