有没有办法区分new和new[]的返回值?

3

考虑以下代码:

int *p = new int;
cout << sizeof(*p);
delete p;

如预期的那样,结果是4。现在,请考虑以下代码:
int *p = new int[10];
cout << sizeof(*p);
delete[] p;

我原本期望得到40(已分配数组的大小),但结果仍然是4

现在,假设我有一个函数int *foo(),返回指向使用newnew[]创建的结构体的指针(但我不知道哪个):

int *p = foo();

我的问题是,是否有一种方法(或者技巧)可以知道p指向单个整数还是整数数组?
请记住,这只是一个理论问题。我不会以这种方式编写真正的代码。

1
更有趣的问题是,为什么即使运行时必须保留此信息,我们仍无法读取大小(项目计数)。 - Christopher
你说得对,既然我知道直接获取它是不可能的,那么知道是否有某种“黑客”方式来检索该值会很好。 - Kanopus
如果你自己做了内存分配器,那么你可以有一个像 get_allocated_size(*ptr) 这样的函数来获取信息。也许一些操作系统有本地调用可以提供这些信息,但这不是 C++ 标准的一部分。 - David
7个回答

4
没有办法做到这一点。但是知道区别,因为你编写的代码调用了newnew[]
顺便说一下,原因是:
 cout << sizeof(*p);

在这两种情况下都给出4的原因是p是指向int的指针,表达式*p表示被该指针指向的东西(即int),并且在您的平台上int的大小为4。所有这些都在编译时进行评估,因此即使new[]返回特殊值,sizeof也无法使用它。


3
不行,因为你的结果是一个地址(所以在两种情况下sizeof()都返回4)。这个地址是由你创建的,所以你应该知道它是什么。

2

在这两个示例中,变量p的类型相同:int *。sizeof操作的是类型而不是数据。它在编译时计算。

你有几个选择。你可以自己跟踪数组大小,或者你可以尝试使用标准库中的容器之一,比如vector< int >。这些容器将为你跟踪大小(例如vector< int >::size())。


2

sizeof(x) 返回声明x所需的内存大小。

这完全没有动态方面。

其中foo是一个bar *时,sizeof(*foo)始终与sizeof(bar)相同。


1

不,没有任何方法。

必要的问题:你为什么需要知道?

如果是因为“我需要知道是否使用delete []还是delete”,那么就一直使用数组,如果由于某种模糊原因你无法确定在自己的代码中使用了哪个,请使用数组。


我很好奇是否有一种方法可以知道数组是否已经被创建,因为当你调用delete[]时,它确实知道要释放的数组的大小。所以数组的大小必须是可用的(至少对于delete[]来说)。我想知道这个值是否可以以某种方式检索到。 - Kanopus
@Kanopus:出于性能的考虑,标准可能不允许这样做。 - user541686
@Kanopus - delete[] 不一定总是需要知道大小,只有在必须调用对象的析构函数时才需要。当它是一个 int 数组时,可能可以不知道大小就将其释放给操作系统。C++ 还提供了 std::vector 来跟踪所有内容。 - Bo Persson
@Bo Persson:你说得对。也许操作系统可以处理一些数组的释放(而不必担心delete[]需要知道项目数量)。然而,当使用对象时,我们可以假设delete[]必须知道对象的数量才能调用它们的析构函数。在第一种情况下(如果我们知道编译器实现),我们可以从操作系统中检索分配内存的大小。在第二种情况下,并假设我们知道编译器的实现,我们可以检索数组中对象的数量吗? - Kanopus
@Kanopus - 有时可能是可行的。例如,MSVC编译器提供了一个用于请求大小的函数。然而,语言并不要求这在任何地方都能正常工作,并提供std::vector作为更好的选择。 - Bo Persson

1
拥有一个能够返回单个项目或数组指针的函数是一个糟糕的设计决策。你可以始终返回大小为1的数组指针:
return new int[1];

0

首先,sizeof(*p) 总是返回一个整数值,因此它总是返回 4

现在,你如何知道 p 是指向 int 还是 int[]

没有标准的方法。但是,你可以通过黑客手段来获取这个信息。例如,如果你尝试打印某些编译器(比如我的情况下是 Linux)中的 p[-1]、p[-2]、...、p[-4] 等,那么你将会看到这些位置的值有一个特定的模式。然而,这只是一种黑客手段,你不能总是依赖它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接