如果我在C ++中有一个指针,让我们说int* array;
,我用
array=new int[10];
然后,我用0,1,2,3初始化数组的所有10个元素...
在那之后,我做array=new int[15];
最初的前10个值是否仍然存在?我不认为,如果我错了,请纠正我。
在C中有函数realloc
,它具有上述效果。在C ++或java中有任何等价物吗?
如何在C ++或Java中动态扩展数组(不使用Vector类,而不是每次在具有双倍容量的另一个数组中复制数组)?
答案 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
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
,不,renew
与new
对应realloc
与malloc
对应的方式。这并不是语言中缺少的东西。它已通过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
这可能是唯一的方法。当然,您可以使用realloc
或memcpy
来复制值,但它基于void指针,对于初学者来说通常会更棘手。希望这有所帮助,不要忘记为这个东西做一个类或一个结构,否则,它将是很多混乱。
编辑: 忘了提,我的答案只包括C ++,没有JAVA。