为什么不能改变数组大小

时间:2014-02-24 23:33:07

标签: c++ c arrays

看起来像一个奇怪的问题但是当我用c ++或c编程时,例如我必须硬编码数组的大小。

用户是否无法通过终端输入尺寸。到目前为止,我似乎无法看出它是否可能,并想知道为什么这是被禁止的。

编辑:

到目前为止,我理解的是数组是静态的,我们可以使用链接列表,因为它更具动态性。为什么cant数组不是动态的?

5 个答案:

答案 0 :(得分:4)

std::vector是一个动态数组。使用它。

可变长度数组do actually exist in Cas a GCC language extension for C++in the forthcoming C++14 by the look of it


在这个答案中,我假设您的意思是可以具有运行时边界的数组,即使这些边界以后不能被更改。这与您问题的内容相匹配,但与其标题不符。幸运的是,std::vector提供两者

我也假设是C ++,因为我们在开什么人开玩笑?

答案 1 :(得分:3)

C

在C99和更新的标准中,您可以使用VLA:

int len = ask_length_from_user();
int array[len];
for (int i = 0; i < len ; ++i) array[i] = i;

请注意,对于VLA,您应该注意大小,因为VLA将存储在堆栈中,这通常非常有限(只有兆字节,而不是千兆字节的最大堆)。

或许更好的方法是使用堆:

int len = ask_length_from_user();
int *array = malloc (sizeof(int) * len);
if (!array) exit(1); // malloc failed
for (int i = 0; i < len ; ++i) array[i] = i;

请注意如何使用与访问数组相同的语法访问已分配的内存。此外,您可以调整使用malloc分配的内存:

int tmplen = ask_length_from_user();
int *tmparr = realloc(array, sizeof(int) * tmplen);
if (tmparr) {
    array = tmparr;
    // note: following loop doesn't do anything if len >= newlen
    while(len < tmplen) array[len++] = len;
}
// else realloc failed, keep original array and len

最后,对于malloc内存,请记住!

free(array);

C ++

您应该使用例如 std :: vector

int len = ask_length_from_user();
std::vector<int> array;
for (int i = 0; i < len ; ++i) array.push_back(i);

// alternatively, you can resize the array and use indexes like in C snippets:
array.resize(len);
for (int i = 0; i < len ; ++i) array[i] = i;

用于调整大小的代码,只需使用push_back

int tmplen = ask_length_from_user();
if (tmplen < len) { 
    len = tmplen;
    array.resize(tmplen);
} else {
    while (len < tmplen) array.push_back(len++);
}

如您所见,C和C ++代码完全不同。它们是不同的语言,对两者都提出同样的问题很少有意义。 C代码(当前标准C ++中的VLA除外)可以在C ++中运行,但这样做不是一个好主意,它不是很好的C ++,至少你应该避免使用malloc并使用new(尽管它不支持很好地调整大小。)

答案 2 :(得分:3)

C的设计决定是内置阵列是一个简单快速的结构,反映了处理器可以廉价实现的操作。在具有可变大小数组的语言中,调整数组大小的行为可能非常昂贵,因为将调用下面的代码来重新分配不同大小的新内存块,并复制现有内容。

在C中,您使用heap和malloc / realloc自行监督这些调整大小操作,因为这就是C语言的类型。 C ++有像std :: vector那样为你做这个的数组,甚至在C中你可以使用库函数来管理动态数组。只是简单的C阵列设计简单快速。

答案 3 :(得分:2)

当你分配一块内存时,你只需要这样做 - 分配你要求的大小的内存块,然后给你一个指向它的指针。

如果您尝试超出该块的末尾,则表示您正在读取/写入不属于该阵列的内存。

为了扩展阵列,你需要更多的内存 - 但你的块不够大。您需要分配一个新块并将指针更改为该新块,您不能通过调整现有块的大小来实现它,因为块之后的空间已被其他东西使用了!

这就是为什么不可能调整现有阵列的大小。

答案 4 :(得分:0)

因为静态(自动)变量是在堆栈上分配的,并且堆栈帧的地址在函数的生命周期内是固定的,所以变量的地址也是静态的。一旦在某个位置声明了一个数组,那么在不重叠其他变量之后就不能使它变大。 C99允许可变长度数组,其大小仅在运行时已知,但它们的大小仍然是固定的,您无法在声明后调整大小。

但是你不需要C99或vector来调整数组的大小。您总是可以在堆上分配动态内存并使用指针作为数组,因为它们在使用这种方式时并不“不同”。通过分配新的内存区域来调整动态内存的大小,并在需要时将数据复制到新位置。