简体   繁体   English

使用变量定义数组大小和使用新的运算符c ++有什么区别?

[英]What's the difference between using a variable to define array size and using the new operator c++?

I'm learning the basics of C++ with previous experience in Java based upon the official tutorial at " http://www.cplusplus.com/doc/tutorial/dynamic/ ". 我基于“ http://www.cplusplus.com/doc/tutorial/dynamic/ ”上的官方教程,学习了Java的基础知识以及以前的Java经验。 The tutorial presents the operator "new" as a way to define a array's size at runtime; 本教程介绍了运算符“ new”,作为在运行时定义数组大小的一种方法。 however, this feels like a useless addition, since I can easily just define an array's size with a variable by doing 但是,这感觉像是无用的加法,因为通过执行以下操作,我可以轻松地使用变量定义数组的大小

int numbers [size];

in contrast to

int * numbers = new int [size];

By testing on my own I already realized that using the new operator allows for going over the pre-allocated memory size (I could write to numbers[7] when I initialized it with size = 5), whereas the first line of code does not. 通过我自己的测试,我已经意识到使用new运算符可以遍历预分配的内存大小(当我用size = 5初始化它时,我可以写到numbers [7]),而第一行代码却没有。 I have three basic questions about this operator: 关于此运算符,我有三个基本问题:

  1. What's the difference between the two lines of code above? 上面两行代码有什么区别?
  2. Is it dangerous to write to a pointer address in memory in the array I didn't allocate to start with? 写入我未分配的数组中的内存中的指针地址是否有危险?
  3. If it is dangerous to do so, what alternative could I use (if there is one) to setting up lists other than manually setting up (or using a library for) a linked list? 如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?

What's the difference between the two lines of code above? 上面两行代码有什么区别?

Assuming size is a constant expression, the difference is the first example is allocated on stack while the second on heap and you need to remember to delete [] it. 假设size是一个常量表达式,则不同之处是第一个示例分配在堆栈上,而第二个示例分配在堆上,您需要记住将其delete []

Is it dangerous to write to a pointer address in memory in the array I didn't allocate to start with? 写入我未分配的数组中的内存中的指针地址是否有危险?

It's undefined behaviour to write outside bounds, but if you're within bounds you're ok: 写越界是不确定的行为,但是如果您在界界内,则可以:

constexpr int size = 5;
int arr[size];
arr[0] = 2;

If it is dangerous to do so, what alternative could I use 如果这样做很危险,我可以使用什么替代方法

Use a std::vector : 使用std::vector

std::vector<int> arr;
 int numbers [size]; 

in contrast to

 int * numbers = new int [size]; 

The first, in standard C++, requires the value of size to be known and fixed at compile time. 首先,在标准C ++中,要求size的值是已知的,并在编译时固定。 The second allows the value of size to be determined at run time (eg based on user input). 第二个允许在运行时确定size值(例如,基于用户输入)。

Some compilers allow the first form to be used with size as a variable, but that is not standard C++. 一些编译器允许将第一种形式与size作为变量一起使用,但这不是标准的C ++。 Such variable length arrays are a feature of C (from 1999) that some C++ compilers support as a non-standard extension. 这种可变长度数组是C(从1999年开始)的一项功能,某些C ++编译器将其作为非标准扩展来支持。 Other C++ compilers will diagnose an error (as required by the C++ standard). 其他C ++编译器将诊断错误(按照C ++标准的要求)。

How the first is allocated depends on context. 第一个的分配方式取决于上下文。 For example; 例如;

  • If outside a function (eg at file scope) it will be allocated statically, and will exist for as long as the program runs. 如果在函数外部(例如,在文件范围内),它将被静态分配,并且将在程序运行时一直存在。
  • If inside a block (eg in a function) arr will have automatic storage duration and will cease to exist at the end of enclosing block (eg when the function returns). 如果在块内(例如,在函数中), arr将具有自动存储持续时间,并且在封闭的块末尾将不存在(例如,函数返回时)。
  • If a member of a struct or class type, the array will be created whenever an instance of that struct or class is created. 如果是structclass类型的成员,则在创建该structclass的实例时将创建该数组。

The first two above are, somewhat incorrectly, sometimes said to be created on "the stack". 上面的前两个有时有些不正确,有时说是在“堆栈”上创建的。 However, the C++ standard does not require that - "the stack" is an implementation detail associated with operating systems and runtime environment. 但是,C ++标准不需要-“堆栈”是与操作系统和运行时环境关联的实现细节。

The second is said to allocate memory dynamically (using operator new ). 据说第二个动态分配内存(使用operator new )。 The memory will exist until it is explicitly released (eg using the corresponding operator delete ). 内存将一直存在,直到将其显式释放为止(例如,使用相应的运算符delete )。

Is it dangerous to write to a pointer address in memory in the array I didn't allocate to start with? 写入我未分配的数组中的内存中的指针地址是否有危险?

Yes. 是。 The behaviour is undefined by the C++ standard. 该行为由C ++标准未定义。 Practically, it can seem to work correctly. 实际上,它似乎可以正常工作。 It can also have unwanted effects, such as poisoning data used by your program or reformatting your hard drive. 它还可能产生不良影响,例如程序中毒数据或重新格式化硬盘驱动器。 In nasty cases, it can seem to work correctly in your testing, only to have one of the unwanted effects when run by a paying client. 在令人讨厌的情况下,它似乎可以在您的测试中正常工作,而只有付费客户运行时,它才会产生不想要的效果之一。 Such occurrences tend to make for grumpy clients. 这种情况往往使脾气暴躁的客户。

The behaviour is equally undefined whether working with a pointer or an array. 无论是使用指针还是使用数组,行为都是同样不确定的。 Assigning a value to the tenth element of an array with five elements gives undefined behaviour, regardless of how the array is created (eg in either of your two options). 将值分配给具有五个元素的数组的第十个元素会产生不确定的行为,而与数组的创建方式无关(例如,在两个选项中的任何一个中)。

If it is dangerous to do so, what alternative could I use (if there is one) to setting up lists other than manually setting up (or using a library for) a linked list? 如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?

In C++, there are standard containers. 在C ++中,有标准容器。 Look up vector (in the standard header <vector> ) for an example. 查找vector (在标准标题<vector> )作为示例。 Obviously it is possible to use a standard container incorrectly (and get unwanted effects) but it is easier to avoid problems using a standard container than it is with arrays or pointers. 显然,可能会错误地使用标准容器(并产生不良影响),但与使用数组或指针相比,使用标准容器更容易避免出现问题。

Standard containers also handle memory allocation and deallocation automatically - there is no need for you, as the programmer, to manage dynamic memory directly (eg forgetting to release the memory when no longer needed). 标准容器还可以自动处理内存分配和释放-作为程序员,您无需直接管理动态内存(例如,在不再需要时忘记释放内存)。

What's the difference between the two lines of code above? 上面两行代码有什么区别?

The difference is that the first one is not allowed in C++. 不同之处在于,C ++中不允许使用第一个。 Some compilers will allow it and may give a warning when special flags are supplied, whereas other compilers retch at the sight of it). 一些编译器会允许它,并且在提供特殊标志时可能会发出警告,而其他编译器会视其为“获取”。

The second one is the way to go and pretty much does the same thing no matter what compiler you use. 第二个是要走的路,无论您使用哪种编译器,几乎都会做同样的事情。

Is it dangerous to write to a pointer address in memory in the array I didn't allocate to start with? 写入我未分配的数组中的内存中的指针地址是否有危险?

Yes it is. 是的。 The behavior is undefined . 行为是不确定的 If you don't get any exception at runtime, don't take that as a good thing because sooner than later, something will break surprisingly. 如果您在运行时没有遇到任何异常,请不要将其视为好事,因为迟早会有一些意外中断。

If it is dangerous to do so, what alternative could I use (if there is one) to setting up lists other than manually setting up (or using a library for) a linked list? 如果这样做很危险,除了手动设置(或使用库)链接列表之外,我可以使用什么替代方法(如果有)来设置列表?

Are you asking for an alternative way to access memory that does not belong to you? 您是否正在寻求一种访问不属于您的内存的替代方法? The answer is DON'T DO IT! 答案是不要做! .

You can use one of C++'s containers as an alternative to creating a list of stuff. 您可以使用C ++的一个容器代替创建东西列表。 For a builtin linked list data structure, use std::list or std::forward_list . 对于内置的链表数据结构,请使用std::liststd::forward_list For random access containers, std::vector is a great start, but if you know the size ahead of time (ie before runtime), then std::array is the way to go. 对于随机访问容器, std::vector是一个很好的开始,但是如果您提前知道大小(即在运行时之前),则可以使用std::array

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

相关问题 在C ++中重载operator new和operator new []有什么区别? - What's the difference between overloading operator new and operator new[] in C++? Java 的 equals() 和 C++ 的运算符 == 有什么区别? - What is the difference between Java's equals() and C++'s operator ==? C++ 数组运算符和 *(array + index) 如果有的话有什么区别? - What is the difference between the C++ array operator and *(array + index) if any? C ++中的operator()和operator &lt;有什么区别? - What is the difference between operator() and operator< in C++? c++ 中的 delete[] 和::operator delete() 有什么区别 - What's the difference between delete[] and ::operator delete() in c++ (C ++)这些重载的运算符函数有什么区别? - (C++) What's the difference between these overloaded operator functions? 在C ++中使用NEW和不使用NEW有什么区别 - What is the difference in using NEW and not using it in C++ 新int和new(int)之间c ++的区别是什么? - What's the difference in c++ between new int and new (int)? 使用定义和变量之间的区别 - Difference between using define and variable 在 C++ 中,数组分配的 new 和 new[] 有什么区别 - In C++, what is the difference between new and new[] for array allocations
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM