【问题标题】:Deleting pointer to array删除指向数组的指针
【发布时间】:2015-07-15 21:24:04
【问题描述】:

在我的一个大型项目中,我遇到了删除未指定大小的初始化数组的问题。
我写了一个简单的程序来检查出了什么问题,这里是代码

#include "stdafx.h"

class Checker
{
public:
    Checker()
    :myI(i++){}

virtual ~Checker(){
    printf("%i " , myI);
    fflush(stdout);
}
private:
    int myI;
    static int i;
};

int Checker::i = 0;


int _tmain(int argc, _TCHAR* argv[]){
    Checker* somePointer;
    Checker* anotherPointer;

    somePointer = new Checker[4]{
        Checker(), Checker(), Checker(), Checker()};

    anotherPointer = new Checker[]{
        Checker(), Checker(), Checker(), Checker()};

    delete[] somePointer;

    delete[] anotherPointer; //approach A
    delete anotherPointer; //approach B
    //in approach C anotherPointer is not deleted

    return 0;
}

如您所见,anotherPointer 在没有明确定义大小的情况下进行了初始化。
当然,一次只有一条标记为进场的线路处于活动状态。
在方法 A 输出看起来像这样( 表示程序意外结束)

 3 2 1 0 <crash> 

在方法 B 中,输出为

 3 2 1 0 4 <crash> 

在方法 C 中,有时输出为 3 2 1 0,而其他时候应用程序崩溃而没有打印任何内容。

据我所知,没有指定数组大小的初始化以不同的内存分配结束,但我不知道如何解决应用程序最终崩溃的问题,这是我的问题。

我正在使用 Visual Studio Pro 2013 Update 4 (MSVC++)

编辑
如果除了明确指定大小之外没有解决该问题的方法,我的问题是
为什么在 MSCC++ 中实现了这个“功能”?

【问题讨论】:

  • 意外结束是什么意思?您收到错误消息吗?
  • g++ 无法编译您的示例代码,即使在摆脱了明显的 MS 主义之后;为“new Checker[]{”发出诊断。这似乎依赖于不可移植的、特定于编译器的特性或行为,而不是标准的 C++。
  • 标准 C++ 的语法似乎不允许 new Checker[] 带有空括号。
  • 接受它看起来像是一个非常明确的编译器错误。对于它的价值,VC++ 2015 的预览版拒绝它,并显示一条错误消息:error C3078: you cannot 'new' an array of unknown bounds
  • @Jefffrey:值得注意的是,即使使用空括号,它也几乎惊人地接近语法正确(但作为 lambda 表达式)。

标签: c++ arrays visual-c++ array-initialization


【解决方案1】:

当前 C++ 标准不允许分配没有明确指定大小的数组(就像在 Java 或 C# 中一样)。 GCC C++ 和 Clang 在尝试编译代码时都会出错(即使在 C++14 模式下)。 Visual Studio 2015 RC 也产生error C3078: you cannot 'new' an array of unknown bounds。总而言之,这不是一个功能,它是 VS 2013 中的一个错误,显然在 VS 2015 中已修复。

【讨论】:

    猜你喜欢
    • 2015-08-09
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多