Enumerable.Repeat has some memory issues?

人走茶凉 提交于 2019-12-13 00:44:45

问题


I initialized an Array as

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

Then in a loop i am incrementing values like

myarr[0][0]++; 

This causes all values like myarr[1][0], myarr[2][0], myarr[3][0] ..... myarr[12][0] to increment by one.

This problem is not occurring when using a for loop (0-12) i am initializing like

myarr[i] = new double[12];

Why is this so?


回答1:


Other answers have explained the problem. The solution is to create a new array on each iteration, e.g.

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



回答2:


It's because new double[12] creates a single array object in memory - Enumerable.Repeat is simply providing you with multiple references to that array.




回答3:


This is expected behavior - array is a referebce type. You are creating a jagged array i.e. array of arrays. All elements of your outer array references the same inside array i.e the first argument of Repeat call, so changes in the inside array will be reflected at on indices (because all indices refer to the same array).




回答4:


With new double[12] you are creating reference to array of doubles, and then you repeate the reference 12 times, so myarr[0..n] will have reference to one memory region.

You can use the folowing method to resolve thw issue

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

Or with custom Repeat method which calls action every step:

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



回答5:


Arrays are references. In the Repeat call you create one array and assign its reference 12 times. In your loop however you create 12 distinct arrays.




回答6:


Repeat() basically just capture and yields the same element multiple times, so you got multiple references to the same object instance in the memory.

This is how Repeat() is implemented:

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


来源:https://stackoverflow.com/questions/10071032/enumerable-repeat-has-some-memory-issues

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!