繁体   English   中英

使用变量定义数组大小和使用新的运算符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]),而第一行代码却没有。 关于此运算符,我有三个基本问题:

  1. 上面两行代码有什么区别?
  2. 写入我未分配的数组中的内存中的指针地址是否有危险?
  3. 如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?

上面两行代码有什么区别?

假设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将具有自动存储持续时间,并且在封闭的块末尾将不存在(例如,函数返回时)。
  • 如果是structclass类型的成员,则在创建该structclass的实例时将创建该数组。

上面的前两个有时有些不正确,有时说是在“堆栈”上创建的。 但是,C ++标准不需要-“堆栈”是与操作系统和运行时环境关联的实现细节。

据说第二个动态分配内存(使用operator new )。 内存将一直存在,直到将其显式释放为止(例如,使用相应的运算符delete )。

写入我未分配的数组中的内存中的指针地址是否有危险?

是。 该行为由C ++标准未定义。 实际上,它似乎可以正常工作。 它还可能产生不良影响,例如程序中毒数据或重新格式化硬盘驱动器。 在令人讨厌的情况下,它似乎可以在您的测试中正常工作,而只有付费客户运行时,它才会产生不想要的效果之一。 这种情况往往使脾气暴躁的客户。

无论是使用指针还是使用数组,行为都是同样不确定的。 将值分配给具有五个元素的数组的第十个元素会产生不确定的行为,而与数组的创建方式无关(例如,在两个选项中的任何一个中)。

如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?

在C ++中,有标准容器。 查找vector (在标准标题<vector> )作为示例。 显然,可能会错误地使用标准容器(并产生不良影响),但与使用数组或指针相比,使用标准容器更容易避免出现问题。

标准容器还可以自动处理内存分配和释放-作为程序员,您无需直接管理动态内存(例如,在不再需要时忘记释放内存)。

上面两行代码有什么区别?

不同之处在于,C ++中不允许使用第一个。 一些编译器会允许它,并且在提供特殊标志时可能会发出警告,而其他编译器会视其为“获取”。

第二个是要走的路,无论您使用哪种编译器,几乎都会做同样的事情。

写入我未分配的数组中的内存中的指针地址是否有危险?

是的。 行为是不确定的 如果您在运行时没有遇到任何异常,请不要将其视为好事,因为迟早会有一些意外中断。

如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?

您是否正在寻求一种访问不属于您的内存的替代方法? 答案是不要做!

您可以使用C ++的一个容器代替创建东西列表。 对于内置的链表数据结构,请使用std::liststd::forward_list 对于随机访问容器, std::vector是一个很好的开始,但是如果您提前知道大小(即在运行时之前),则可以使用std::array

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM