为什么C ++ / CLI参差不齐的托管数组初始化器分配了大量的临时数组?

时间:2014-05-31 09:07:28

标签: c# .net arrays visual-studio-2013 c++-cli

我在工作中分析了一个具有奇怪内存签名的C ++ / CLI项目:它有大量的Commited字节(7GB),但它在工作集中只有大约30MB。我发现问题在于这段代码:

ref class c1
{
public:
    int x;

    static void createArray()
    {
        auto val = gcnew c1;
        auto arr = gcnew array<c1^>(1) { val };
        auto jagged= gcnew array<array<c1^>^>{ arr };

        //Make sure the array doesn't get optimized away
        Console::WriteLine(jagged[0][0]->x);
    }
};

我期待jaged的初始化在C#中翻译成类似的东西:

var jagged = new c1[][] { arr };

相反,使用ILSpy,我发现它实际上转换为类似的东西(反编译优化的二进制文件:

public static void createArray()
{
    c1 val = new c1();
    c1[] array = new c1[]
    {
        val
    };
    c1[][] array2 = new c1[][]
    {
        new c1[12648430] //the constant is equal to 0xC0FFEE
    };
    array2[0] = array;
    Console.WriteLine(array2[0][0].x);
}

我发现很难理解它为什么要分配一个12648430元素的临时数组。但是,我也很难想象在Visual Studio 2013专业版MSVC编译器中实际发布了这样的错误,但我想不出任何其他解释。

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

这实际上是C ++ / CLI编译器实现中的一个错误。微软意识到了这个问题,但他们暂时不会修复它。

可以在错误报告here中找到更多详细信息。

该报告还提出了两个简单的解决方法:

  1. 手动初始化数组,而不是使用初始化列表。

  2. 使用二维数组而不是锯齿状数组。