在许多教程中,关于动态内存的第一个代码示例开始于:
int * pointer;
pointer = new int; // version 1
//OR
pointer = new int [20]; // version 2
他们总是着手解释第二个版本是如何工作的,但完全避免谈论第一个版本。
我想知道的是,pointer = new int
创造了什么?我该怎么办?这是什么意思?每个教程都没有失败,将避免完全讨论第一个版本。所有我发现的(通过搞乱)都是这样的:
#include <iostream>
using namespace std;
int main()
{
int * pointer;
pointer = new int;
pointer[2] = 1932; // pointer [2] exists? and i can assign to it?!
cout << pointer[2] << endl; // ... and access it successfully?!
};
我可以下标pointer
这一事实告诉我,pointer = new int
隐式创建了一个数组。但如果是这样,那么它的大小是多少?
如果有人可以帮我清除这一切,我将不胜感激......
答案 0 :(得分:13)
对于初学者来说,这是C和C ++中的典型错误。第一句话,创造了一个只容纳int
的空间。第二个创建了一个空间来容纳那些int
中的20个。但是,在这两种情况下,它都会将动态保留区域的开头地址分配给pointer
变量。
为了增加混乱,即使他们指向的内存无效,您也可以访问带索引的指针(当您放置pointer[2]
时)。在以下情况下:
int* pointer = new int;
您可以访问pointer[2]
,但您有未定义的行为。请注意,你必须检查这些访问是否实际发生,并且编译器通常可以很少地防止此类错误。
答案 1 :(得分:11)
我老师这样说了。
想想电影。实际的座位是内存分配,你得到的票是指针。
int * pointer = new int;
这将是一个有一个座位的电影院,指针将成为该座位的门票
pointer = new int [20]
这将是一个有20个座位的电影院,指针将是第一个座位的门票。指针[1]将成为第二个座位的票证,指针[19]将成为最后一个座位的票证。
当您执行int* pointer = new int;
然后访问pointer[2]
时,您会让某人坐在过道中,这意味着未定义的行为
答案 2 :(得分:9)
这只会创建一个整数。
pointer = new int; // version 1
这会创建20个整数。
pointer = new int [20] // version 2
以下是无效的,因为指针[2]转换为*(指针+ 2);尚未创建/分配。
int main()
{
int * pointer;
pointer = new int;
pointer[2] = 1932; // pointer [2] exists? and i can assign to it?!
cout << pointer[2] << endl; // ... and access it succesfuly?!
};
干杯!
答案 3 :(得分:2)
new int[20]
为大小 20 的整数数组分配内存,并返回指向它的指针。
new int
只为一个整数分配内存,并返回指向它的指针。隐含地,这与new int[1]
相同。
你可以在两个指针上取消引用(即使用*p
),但是你应该只对p[i]
返回的指针使用new int[20]
。
p[0]
仍然会对两者都有效,但你可能会搞砸并错误地输入错误的索引。
更新:另一个区别是您必须对数组使用delete[]
,并为整数使用delete
。
答案 4 :(得分:1)
pointer = new int
在堆上分配足够的内存来存储一个int
。
pointer = new int [20]
分配内存以存储20 int
s。
两个调用都返回指向新分配内存的指针。
注意:不要依赖正在初始化的已分配内存,它可能包含随机值。
答案 5 :(得分:1)
pointer = new int;
分配一个整数并将其地址存储在pointer
中。 pointer[2]
是pointer + 2
的同义词。要理解它,请阅读指针算法。这一行实际上是未定义的行为,因为你正在访问以前没有分配过的内存,而且它很有用,因为你很幸运。
答案 6 :(得分:1)
* “我可以下标指针的事实告诉我,我pointer = new int
隐式创建了一个数组。但如果是这样,那么它的大小是多少?”
*
这是我最喜欢和你强调的问题的一部分。
众所周知,动态内存分配利用了Stack上特定于给定程序的空间。 当我们仔细研究新运算符的定义时: -
void* operator new[] (std::size_t size) throw (std::bad_alloc);
这实际上代表了特定大小的对象数组,如果成功,那么它会自动构造数组中的每个对象。因此,我们可以自由地使用大小范围内的对象,因为它已经被初始化/构建。
int * pointer = new int;
另一方面,对于上面的例子,当任何
时,都存在未定义行为的所有可能性*(pointer + k) or *(k + pointer)
被使用。虽然可以使用指针访问特定的内存位置,但是不能保证因为它的特定Object没有被创建或构造。这可以被认为是没有在特定程序的堆栈上分配的空间。
希望这会有所帮助。
答案 7 :(得分:0)
int* p = new int
为一个整数分配内存。它并不意味着创建一个数组。使用p[2]
访问指针的方式将导致未定义的行为,因为您正在写入无效的内存位置。只有在使用new[]
语法时才能创建数组。在这种情况下,您需要使用delete[]
释放内存。如果您使用new
分配了内存,则表示您正在创建单个对象,并且需要使用delete
释放内存。
答案 8 :(得分:0)
它不会创建数组。它创建一个整数并返回指向该整数的指针。当您编写指针[2]时,您将引用尚未分配的内存。你需要小心,不要这样做。可以从外部程序中编辑该内存,我相信,您不希望这样做。
答案 9 :(得分:0)
int * pointer; pointer = new int; // version 1
//OR
pointer = new int [20] // version 2
我想知道的是,
pointer = new int
创造了什么?我该怎么办?这是什么意思?每个教程都没有失败,将避免完全讨论第一个版本
本教程没有告诉你该怎么做的原因是它真的 完全没用!它分配一个int
并为您提供指向它的指针。
问题是,如果你想要一个int,为什么不直接声明一个呢?
int i;