![](/img/trans.png)
[英]What's the difference between overloading operator new and operator new[] in C++?
[英]What's the difference between using a variable to define array size and using the new operator c++?
我基于“ http://www.cplusplus.com/doc/tutorial/dynamic/ ”上的官方教程,学习了Java的基础知识以及以前的Java经验。 本教程介绍了运算符“ new”,作为在运行时定义数组大小的一种方法。 但是,这感觉像是无用的加法,因为通过执行以下操作,我可以轻松地使用变量定义数组的大小
int numbers [size];
与
int * numbers = new int [size];
通过我自己的测试,我已经意识到使用new运算符可以遍历预分配的内存大小(当我用size = 5初始化它时,我可以写到numbers [7]),而第一行代码却没有。 关于此运算符,我有三个基本问题:
上面两行代码有什么区别?
假设size
是一个常量表达式,则不同之处是第一个示例分配在堆栈上,而第二个示例分配在堆上,您需要记住将其delete []
。
写入我未分配的数组中的内存中的指针地址是否有危险?
写越界是不确定的行为,但是如果您在界界内,则可以:
constexpr int size = 5;
int arr[size];
arr[0] = 2;
如果这样做很危险,我可以使用什么替代方法
使用std::vector
:
std::vector<int> arr;
int numbers [size];
与
int * numbers = new int [size];
首先,在标准C ++中,要求size
的值是已知的,并在编译时固定。 第二个允许在运行时确定size
值(例如,基于用户输入)。
一些编译器允许将第一种形式与size
作为变量一起使用,但这不是标准的C ++。 这种可变长度数组是C(从1999年开始)的一项功能,某些C ++编译器将其作为非标准扩展来支持。 其他C ++编译器将诊断错误(按照C ++标准的要求)。
第一个的分配方式取决于上下文。 例如;
arr
将具有自动存储持续时间,并且在封闭的块末尾将不存在(例如,函数返回时)。 struct
或class
类型的成员,则在创建该struct
或class
的实例时将创建该数组。 上面的前两个有时有些不正确,有时说是在“堆栈”上创建的。 但是,C ++标准不需要-“堆栈”是与操作系统和运行时环境关联的实现细节。
据说第二个动态分配内存(使用operator new
)。 内存将一直存在,直到将其显式释放为止(例如,使用相应的运算符delete
)。
写入我未分配的数组中的内存中的指针地址是否有危险?
是。 该行为由C ++标准未定义。 实际上,它似乎可以正常工作。 它还可能产生不良影响,例如程序中毒数据或重新格式化硬盘驱动器。 在令人讨厌的情况下,它似乎可以在您的测试中正常工作,而只有付费客户运行时,它才会产生不想要的效果之一。 这种情况往往使脾气暴躁的客户。
无论是使用指针还是使用数组,行为都是同样不确定的。 将值分配给具有五个元素的数组的第十个元素会产生不确定的行为,而与数组的创建方式无关(例如,在两个选项中的任何一个中)。
如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?
在C ++中,有标准容器。 查找vector
(在标准标题<vector>
)作为示例。 显然,可能会错误地使用标准容器(并产生不良影响),但与使用数组或指针相比,使用标准容器更容易避免出现问题。
标准容器还可以自动处理内存分配和释放-作为程序员,您无需直接管理动态内存(例如,在不再需要时忘记释放内存)。
上面两行代码有什么区别?
不同之处在于,C ++中不允许使用第一个。 一些编译器会允许它,并且在提供特殊标志时可能会发出警告,而其他编译器会视其为“获取”。
第二个是要走的路,无论您使用哪种编译器,几乎都会做同样的事情。
写入我未分配的数组中的内存中的指针地址是否有危险?
是的。 该行为是不确定的 。 如果您在运行时没有遇到任何异常,请不要将其视为好事,因为迟早会有一些意外中断。
如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?
您是否正在寻求一种访问不属于您的内存的替代方法? 答案是不要做! 。
您可以使用C ++的一个容器代替创建东西列表。 对于内置的链表数据结构,请使用std::list
或std::forward_list
。 对于随机访问容器, std::vector
是一个很好的开始,但是如果您提前知道大小(即在运行时之前),则可以使用std::array
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.