删除没有指定大小的指针数组

时间:2014-02-28 23:39:04

标签: c++ arrays pointers delete-operator

我无法弄清楚为什么在VS2013中编译的以下C ++代码会导致崩溃。

#include "stdafx.h"

class A {};

void main()
{
    A** arr1 = new A*[5] { new A(), new A(), new A(), new A(), new A() };
    delete[] arr1;
    A** arr2 = new A*[] { new A(), new A(), new A(), new A(), new A() };
    delete[] arr2;
}

第一个数组被正确初始化和删除,但第二个数组导致delete[] arr2行上出现“%Filename%.exe已触发断点”异常,然后是调试断言:

File: f:\dd\vctools\crt\crtw32\misc\dbgheap.c
Line: 1322

Expression: _CrtIsValidHeapPointer(pUserData)

这两个数组之间的区别非常明显:一个具有明确指定的长度,另一个没有。但是,编译器是否应该足够聪明地确定以下初始化列表中项目数的长度?因为如果数组由原始对象组成(即A* arr = new A[] { A(), A(), A() }),它就可以了。

请指出我做错了什么或解释背后的原因。

忽略数组项的内存泄漏。它们在真实程序中被删除,这一个很快就被拼凑起来进行演示。崩溃发生在任何一种方式。

2 个答案:

答案 0 :(得分:1)

要了解实际情况,我尝试重载newdelete运算符。我尝试重载new[]delete[],但是VS2013说它已经在一些.lib文件中定义了..所以以下内容将要做..(请注意,我从未重载过新的或删除之前所以我希望这是对的)

这是一个32位程序sizeof(int) = 4

#include "stdafx.h"
#include <iostream>

void* operator new(std::size_t size) //this is called..
{
    std::cout << "Allocated: "<<size<<"\n";
    return malloc(size);
}

void operator delete(void* ptr) //this function never gets called.
{
    std::cout << "DeAllocated\n";
    free(ptr);
}

int main()
{
    int** arr1 = new int*[2] {new int(1), new int(2)};
    delete[] arr1;

    std::cout << "\n\n";

    int** arr2 = new int*[] {new int(3), new int(4)};
    delete[] arr2;
}

结果是:

Allocated: 8
Allocated: 4
Allocated: 4


Allocated: 0
Allocated: 4
Allocated: 4

那么8来自哪里?嗯?

让我们将第一个例子改为:

int** arr1 = new int*[3] {new int(1), new int(2), new int(3)};

和第二个:

int** arr2 = new int*[] {new int(4), new int(5), new int(6)};

结果现在是:

Allocated: 12
Allocated: 4
Allocated: 4
Allocated: 4


Allocated: 0
Allocated: 4
Allocated: 4
Allocated: 4

你看到现在发生了什么吗?第二个似乎是分配错误的大小。换句话说,我认为arr2的大小为0,而arr1的大小为12 ..只是猜测我的结果是什么意思。

答案 1 :(得分:0)

g ++ 2.8.1不会编译arr2:

foo8.cpp: In function ‘int main()’:
foo8.cpp:7:23: error: expected primary-expression before ‘]’ token
     A** arr2 = new A*[] { new A(), new A(), new A(), new A(), new A() };
                   ^
foo8.cpp:7:71: error: too many initializers for ‘A* [1]’
     A** arr2 = new A*[] { new A(), new A(), new A(), new A(), new A() };

采用@CantChooseUsernames发现的内容,我猜有一些关于c ++ 11的微妙内容我不知道,我不明白为什么(就初始化列表而言)是一个不同的情况:

A arr3[] {A(),A(),A()};

编译得很好。