java或c ++中的动态分配

时间:2013-06-26 13:58:17

标签: java c++ memory dynamic allocation

如果我在C ++中有一个指针,让我们说int* array;,我用

为数组分配内存
array=new int[10];

然后,我用0,1,2,3初始化数组的所有10个元素... 在那之后,我做array=new int[15]; 最初的前10个值是否仍然存在?我不认为,如果我错了,请纠正我。

在C中有函数realloc,它具有上述效果。在C ++或java中有任何等价物吗? 如何在C ++或Java中动态扩展数组(不使用Vector类,而不是每次在具有双倍容量的另一个数组中复制数组)?

9 个答案:

答案 0 :(得分:3)

每当new int[X] X array = new int[10]; array[0] = 0; array[1] = 1; // etc array = new int[15]; 为整数时,在C ++和Java中,都会获得对新分配数组的引用。

在Java中,数组会自动初始化,以便每个条目都有其默认值(原始数据类型为0,参考数据类型为null)。在C ++中,数组没有被初始化,你就会得到垃圾。

如果你这样做:

array

第二次创建数组并在变量Arrays.copyOf中添加对它的引用时,您只是丢失了对第一个数组的引用。由于它是一个 new 数组,它将遵循新分配数组的语言规则:在Java中,数组现在指向一个用零填充的大小为15的数组;在C ++中,数组将指向一个填充垃圾的大小为15的数组。

在Java中,丢失的数组最终将为您收集垃圾。在C ++中,您刚刚创建了内存泄漏。

两种语言都禁止调整大小,或者如你所说,动态扩展一个数组。您可以创建一个新的,从旧的复制到新的一个,并丢弃旧的。他们可能会提供为您执行这些操作的方法,但您不会扩展现有数组,只需创建一个新数组并将数据从旧数据复制到新数组。

在Java中没有 realloc (但它有realloc,它的工作原理类似),而在C ++(和C也是如此)中,{{1}}不会真正< em> extend 数组;它将在其他地方分配更多内存,释放先前分配的内存,并返回新指针:你必须替换任何现有的指向新地址的指针!

最后,对于动态调整自身大小的集合类,它们通常有一个内部数组,每当该数组变满时,该类会在内部调整大小:它分配一个更大的,更大的,复制元素,并丢弃旧的。由于数组完全封装在类中,因此您无需担心如上所述对旧数组的引用。

答案 1 :(得分:2)

数组概念的核心,无论是C ++还是Java,都是固定大小的集合。 realloc在这个概念中可能看起来像某种后门,但它仍然不承诺扩展给定的数组 - 它可以在其他位置创建数组,复制原始内容并释放原始内存。很可能它会 因此,如果您想要可变大小的集合,请在C ++中使用std::vector,在Java中使用ArrayList。或者您可以自己编写此功能。但是我担心你必须从自己的内存分配器开始,因为一旦分配了一块内存,就无法进行标准扩展。

答案 2 :(得分:1)

  

最初的前10个值是否仍然存在?

在C ++中,会有某处,但你已经失去了对它们的处理。他们将无法进入。这构成了内存泄漏。

int* array=new int[10]; // array points to dynamically allocated array
array=new int[15]; // array points to a completely different place now

在上面的示例中,array指针是您在第一个动态分配的数组上唯一的句柄。通过使其指向其他地方,您泄漏了数组。

另请注意,在C ++中,数组的元素未初始化为零。为此,您需要初始化数组的值:

int* array=new int[10]();
//                    ^^

答案 3 :(得分:1)

在java内存管理中受JVM的控制。这是java的美丽。您可以使用System.arraycopy()函数制作数组的副本。如果您的目标是扩展数组,只需将更大的数组作为目标数组。

另一方面,您可以使用集合框架来动态扩展集合。

答案 4 :(得分:0)

在Java中,您无法动态扩展数组。像ArrayList一样有不同的数据结构。

在Java中,在您的示例中,如果没有对第一个大小为10的数组进行引用,它将由GarbageCollector收集。

答案 5 :(得分:0)

在C ++中,new总是返回一个指针。 数组的名称是指向数组中第一个元素的指针,所以这里会发生什么。

 int *array;           //get a point of type int
 array=new int[10];    //allocate 10 ints, and set the array ponter to the first one

 array = new int[15]   //allocate 15 ints, and set the array pointer to the first one
问题是现在我们无法知道前10个整数在内存中的位置。操作系统“认为”我们正在使用它b / c我们要求它。但我们不能使用它b / c我们不知道它在哪里。


现在有用了。使用向量,向量是c ++中具有内置动态内存分配的对象,因此您不必亲自手动执行此操作。

如果你真的想看看它是如何完成的,你可以创建自己处理内存分配的对象。

答案 6 :(得分:0)

  

如何在Java中动态扩展数组(不使用Vector类,而不是每次在具有双倍容量的另一个数组中复制数组)?

java.util.Arrays中,有很多方法可供使用。在您的情况下,您需要copyOf

Api Docs

array = Arrays.copyOf(array, 15);

答案 7 :(得分:0)

是的,C ++中有一个等价的标准C ++。

std::vector<int> array(10);

然后

array.resize(15);

vector完全按照您的预期管理其存储内存。 vector旨在取代C的重新分配的数组指针。要替换堆栈上的数组,从C ++ 11开始就有std::array。要替换堆栈上的VLA,您将在C ++ 14或C ++ 17中使用std::dynarray

不要被诱惑,realloc偶尔会复制其数据。 (如果找不到足够的空间来获取重新分配的缓冲区)

关于C ++的等效realloc,不,renewnew对应reallocmalloc对应的方式。这并不是语言中缺少的东西。它已通过std::vector类解决。它管理它的内存本身,它是高效的,不,它不是无法使用它的样式。这是C ++中有一个可以调整大小的数组的标准方法。

答案 8 :(得分:0)

C ++中最好的选择是stl和std::vector<int>我不知道为什么你不能使用它但是让我们说你做不到。可能是最好的方式:

const int c_startSize = 10;
const int c_increasing = 13;   //1.3

int * array;
int arraySize = c_startSize;
array = new int[arraySize];
//some code
//now we need to increase size of array.
int * tmp;
tmp = new int[arraySize * c_increasing / 10];
for (int i = 0; i < arraySize; i++)
    tmp[i] = array[i];
arraySize = arraySize * c_increasing / 10;
delete [] array;
array = tmp;
//some code

这可能是唯一的方法。当然,您可以使用reallocmemcpy来复制值,但它基于void指针,对于初学者来说通常会更棘手。希望这有所帮助,不要忘记为这个东西做一个类或一个结构,否则,它将是很多混乱。

编辑: 忘了提,我的答案只包括C ++,没有JAVA。