为什么数组中的每个元素都应该在c#中再次分配

时间:2013-05-07 14:15:24

标签: c# c++ .net memory-management console-application

以下是我写的代码 Calc[] calculators = new Calc[10]; calculators[0].AddToSum(10);(编写相应的类和方法)。 但我得到了#34;对象引用未设置为对象的实例"然后通过一些研究我通过以下方式删除了异常。

for (int i = 0; i < 10; i++)
        {
            calculators[i] = new Calc();
        }  

有人可以解释为什么我们需要再次分配内存,这与c / c ++不同。 这就是我在c ++中的表现:

Calculator *calc=new Calculator[10]//I know I need to check for std::bad_alloc exception
calculators[0].AddToSum(10); 
delete[] calc;

6 个答案:

答案 0 :(得分:5)

在C#中,有引用类型,并且有值类型。类是引用类型。创建引用类型的变量时,您将创建引用,而不是对象。引用的默认状态为null。如果您希望它引用一个对象,则必须使用new显式初始化它,或者从另一个初始化引用中指定if。

C ++没有这种区别。每种类型都是值类型(尽管您也可以创建对任何类型的引用)。创建值类型的变量时,您将创建一个对象。

答案 1 :(得分:1)

在新的Calc [10]中,您正在分配和调整数组大小。在新的Calc()中,您正在创建实际的Calc对象

答案 2 :(得分:1)

但你会在这句话中得到同样的错误

Calc calc; 
calc.AddToSum(10);

在您指定值之前,对象为空。

Calc [] calculators = new Calc [10];不分配。

基于本杰明(+1)的答案,如果Calc是参考类型,它就有效 你能让Calc成为一个结构吗?

答案 3 :(得分:0)

我不认为你再次分配内存,但你仍然需要为calculators[0]实例化一些值。

在您的第一个代码段中,您尝试在.AddToSum的值上调用Null

Ps:您可以执行以下操作,从头开始初始化每个Calc

Calc[] calculators = new Calc[10]{  
                                   new Calc(), 
                                   new Calc(), 
                                   ..., 
                                   // Repeat 10 times to match array length
                                  };

更新:回应以下评论;好的,试试这个:

calc[] calculators = Enumerable.Repeat(new Calc(), 127).ToArray<Calc>();

答案 4 :(得分:0)

在c ++中创建对象数组时,为每个对象的所有字段分配内存。因此,如果您的对象有两个整数字段并且您创建了一个大小为2的数组,则会分配足够的内存来容纳四个整数。

另一方面,在c#中创建一个正在创建的对象数组和引用数组(指向对象的指针)。因此,除非为每个引用分配内存(使用new),否则无法存储实例。

c ++中的同样的事情是制作一个指针数组,然后你必须实例化数组的每个元素。

答案 5 :(得分:-2)

您的C ++代码也是错误的。 在C ++中,您已经为10个Calculator对象分配了一个包含空格的数组。 当你进行操作时,它从那个(未初始化的)内存中读取,抓取一个值,然后添加它,然后将其写回。 但是你有一个未初始化的对象可以从中开始。

它可能在C ++中有效,因为你有一个不需要调用构造函数的对象(Calculator)。如果它有任何初始化需要调用构造函数,它将无法工作。如果您要使用调试器并在Calculator构造函数中放置断点,您将看到它从未被调用过。

无论如何,要直接回答这个问题,这就是C#的工作方式。分配数组会为数组创建空间,但是数组中的所有对象(假设对象类型)在它们自己分配之前都是空的。

这样想:我创建一个数组来保存10个X类对象。但是X有一个构造函数,它接受一个字符串,我想用每个对象的不同字符串调用它。如果没有明确地创建这10个对象中的每一个并将正确的字符串传递给每个构造函数,人们将如何这样做?