使用新数组创建而不声明大小

问题描述 投票:-1回答:3

这已经困扰了我好一段时间了。我有一个指针。我声明了一个类型为int的数组。

int* data;
data = new int[5];

我相信这会创建一个大小为5的int数组。因此,我将能够从data [0]到data [4]存储值。

现在我以相同的方式创建数组,但是没有大小。

int* data;
data = new int;

我仍然能够将值存储在data [2]或data [3]中。但是我创建了一个大小为1的数组。这怎么可能?

我知道数据是一个指向数组第一个元素的指针。尽管我没有为下一个元素分配内存,但是我仍然可以访问它们。怎么样?

谢谢。

c++ arrays new-operator
3个回答
1
投票

new int仅分配1个整数。如果您访问的偏移量大于0,例如data[1]您覆盖内存。


0
投票

超出C ++中数组的边界是未定义的行为,因此任何事情都可能发生,包括看起来“正确”地工作。

在常见系统的实际实现术语中,您可以将“虚拟”内存视为从0到指针大小的大“平坦”空间,并且指针进入该空间。

进程的“虚拟”内存已映射到物理内存,页面文件等。现在,如果您访问未映射的地址,或尝试编写只读部分,则会收到错误消息,例如作为访问冲突或段错误。

但是此映射是针对相当大的块进行的,以提高效率,例如4KiB“页面”。进程中的分配器,例如newdelete(或堆栈),将根据需要进一步拆分这些页面。因此访问有效页面的其他部分不太可能引发错误。

这具有不幸的结果,可能难以检测到这种超出范围的访问,在释放之后使用等。在许多情况下,写操作将成功,只会破坏其他一些看似无关的对象,这可能会在以后导致崩溃;或者错误的程序输出,因此最好对C和C ++内存管理非常小心。

data = new int; // will be some virtual address
data[1000] = 5; // possibly the start of a 4K page potentially allowing a great deal beyond it 
other_int = new int[5];
other_int[10] = 10;
data[10000] = 42; // with further pages beyond, so you can really make a mess of your programs memory
other_int[10] == 42; // perfectly possible to overwrite other things in unexpected ways

C ++提供了许多工具来帮助,例如std::stringstd::vectorstd::unique_ptr,通常最好完全避免使用手册newdelete


0
投票

通常,不需要分配带有new的数组。改为使用std::vector<int>更方便,也更安全。

[std::vector<int>可选地通过at()方法为元素访问提供边界检查。

示例:

#include <vector>
int main() {
    std::vector<int> data(5);
    data[3] = 10; // element access without bounds checking
    data.at(10) = 0; // invalid element access triggers a runtime exception
}

C ++中的默认模式通常是允许您以未定义的行为射击自己的脚。

供参考:

© www.soinside.com 2019 - 2024. All rights reserved.