|
|
1
112
到目前为止给出的答案似乎没有解决一个问题:如果运行时库(实际上不是操作系统)可以跟踪数组中的事物数量,那么我们为什么需要
这个问题的答案可以追溯到C++作为C兼容语言的根源(它不再真正努力成为C兼容语言。)Stroustrup的哲学是程序员不应该为他们不使用的任何功能付费。如果他们不使用数组,那么他们就不必为每个分配的内存块承担对象数组的成本。 也就是说,如果你的代码只是
那么分配给的内存空间
由于只设置了数组分配来携带额外的数组大小信息,因此您需要告诉运行时库在删除对象时查找该信息。这就是为什么我们需要使用
而不是仅仅
如果bar是一个指向数组的指针。
|
|
|
2
105
编译器不知道这是一个数组,它信任程序员。删除指向单个对象的指针
编译器确实必须以某种方式跟踪需要删除多少对象。它可以通过过度分配来存储数组大小来实现这一点。有关更多详细信息,请参阅 C++ Super FAQ . |
|
|
3
30
是的,操作系统在后台保留了一些东西。例如,如果你跑步
操作系统可以分配4个额外的字节,将分配的大小存储在分配的内存的前4个字节中,并返回一个偏移指针(即,它分配了1000到1024个内存空间,但返回的指针指向1004,位置1000-1003存储了分配的大小)。然后,当调用delete时,它可以查看指针传递给它之前的4个字节,以找到分配的大小。
|
|
|
4
13
this 问题,它有很多你想要的细节。 但可以说,跟踪这些并不是操作系统的工作。实际上是运行时库或底层内存管理器将跟踪数组的大小。这通常是通过预先分配额外的内存并将数组的大小存储在该位置来实现的(大多数使用头节点)。 通过执行以下代码,可以在某些实现上查看这一点
|
|
|
5
9
不管怎样,混合
|
|
|
6
6
它不知道这是一个数组,这就是为什么你必须提供
|
|
|
7
5
我也有类似的问题。在C中,您可以使用malloc()(或其他类似函数)分配内存,并使用free()删除它。只有一个malloc(),它只是分配一定数量的字节。只有一个free(),它只接受一个指针作为参数。
我了解到,答案与类析构函数有关。 如果你分配了一个类MyClass的实例。..
使用delete删除它,您可能只会得到调用MyClass的第一个实例的析构函数。如果您使用delete[],可以确信会对数组中的所有实例调用析构函数。 这是重要的区别。如果你只是使用标准类型(例如int),你就不会真正看到这个问题。另外,您应该记住,在new[]上使用delete和在new上使用delete[]的行为是未定义的——它可能不会在每个编译器/系统上都以相同的方式工作。 |
|
|
8
3
这取决于负责内存分配的运行时,就像你可以使用free删除标准C中用malloc创建的数组一样。我认为每个编译器都有不同的实现方式。一种常见的方法是为数组大小分配一个额外的单元格。 然而,运行时不够智能,无法检测它是数组还是指针,你必须通知它,如果你错了,你要么没有正确删除(例如,用ptr代替数组),要么你最终为大小取了一个无关的值并造成了重大损害。 |
|
|
9
3
编译器的一种方法是分配更多的内存,并在head元素中存储元素计数。 示例如何完成: 这里
编译器将分配sizeof(int)*5个字节。
并设置
所以
和
将按以下方式处理
|
|
|
10
1
从语义上讲,C++中两个版本的delete运算符都可以“吃掉”任何指针;但是,如果给一个指向单个对象的指针
如果编译器可以自动确定传递给delete运算符的指针是否是指针数组,那么C++中只有一个delete运算符,这两种情况都足够了。 |
|
|
11
1
同意编译器不知道它是否是数组。这取决于程序员。 编译器有时会通过过度分配来存储数组大小,从而跟踪需要删除多少对象,但并不总是必要的。 有关分配额外存储的完整规范,请参阅C++ABI(编译器是如何实现的): Itanium C++ ABI: Array Operator new Cookies |
|
|
12
1
这里通常有两层。底层内存管理器和C++实现。 大多数内存管理器都是为满足C语言的需求而设计的。在C中,“free”函数不要求用户指定块的大小。因此,内存管理器将记住(除其他事项外)分配的内存块的大小。这可能比C++实现所要求的块大。通常,内存管理器会在分配的内存块之前存储元数据。 C++有一种“你只为你使用的东西付费”的文化。因此,C++实现通常只会在出于自身目的需要时记住数组的大小,这通常是因为该类型具有非三价析构函数。 因此,对于具有平凡析构函数的类型,“delete”和“delete[]”的实现通常是相同的。C++实现只是将指针传递给底层内存管理器。有点像
另一方面,对于具有非平凡析构函数的类型,“delete”和“delete[]”可能会有所不同。“delete”类似于(其中T是指针指向的类型)
|
|
|
13
0
您不能使用 删除 对于数组,您不能使用 删除[] 对于非数组。 |
|
|
14
-1
嘿,好吧,这取决于你用new[]表达式分配什么。当你分配内置类型或类/结构的数组,而你没有提供构造函数和析构函数时,运算符会将其视为大小“sizeof(object)*numObjects”,而不是对象数组,因此在这种情况下,分配的对象数量不会存储在任何地方,但是如果你分配对象数组,并在对象中提供构造函数和构造函数,而不是行为更改,新表达式将多分配4个字节,并在前4个字节中存储对象数量,这样每个对象的析构函数都可以被调用,因此new[]表达式将返回向前移动4个字节的指针,而不是返回内存时delete[]表达式将调用一个函数首先,迭代对象数组,并为每个对象调用析构函数。我创建了这个简单的代码,它重载了new[]和delete[]表达式,并提供了一个模板函数来释放内存,并在需要时为每个对象调用析构函数:
|
|
|
15
-2
只需在类中定义一个析构函数,并使用这两种语法执行代码
根据输出,u可以找到解决方案 |
|
|
16
-3
答案是:
int大小=*(pArray-1); 上面发布的内容不正确,并产生无效值。 在64位Windows操作系统上,正确的缓冲区大小位于Ptr-4字节地址中 |
|
|
Fishie · 作为类成员的智能指针是否仍然自动释放?[关闭] 1 年前 |
|
|
Anka Hanım · 关于结构和动态数组地址的问题 1 年前 |
|
|
tTt · 使用堆栈中的值重新分配指针 1 年前 |
|
|
manuel · 现代C中空指针的替代方案++ 1 年前 |