堆上具有初始值设定项的多维数组


int ** foo()
{
    int ** multiArray = new int*[3];
    int one[3] = { 1, 2, 3 };
    int two[3] = { 4, 5, 6 };
    int three[3] = { 7, 8, 9 };
    multiArray[0] = one;
    multiArray[1] = two;
    multiArray[2] = three;
    return multiArray;
}

返回 multiArray 在上述函数之外工作,但我对内部箭头(一、二、三(的分配方式有所保留。我的第一反应是它们被分配到堆栈上,而不是堆上。我想要一堆。即使它们以某种方式在该功能之外为我工作,当我尝试按应有的方式删除它们时,它会失败。

如果我做以下事情:

int ** allocatedMultiArray = foo();
int test = allocatedMultiArray[0][2]; // We get 3! Success!
for (int i = 0; i < 8; ++i)
{
     delete[] allocatedMultiArray[i]; // FAILS!
}
delete[] allocatedMultiArray; // WORKS! (If we skip the above for loop of course)

我正在阅读有关多维数组的页面,他特别必须对上面的 for 循环来释放 2D 数组(或 3D 数组的附加循环(。但是,回到我的 foo((,他使用带有循环的新运算符手动将数组分配给堆,而不是 { 1, 2, 3 } 初始化数组然后像我一样分配它。http://www.cplusplus.com/forum/articles/7459/

因此,如果我跳过失败的 for 循环,我是否泄漏了内存?我正在做的事情应该有效吗?我真的不想遍历 multiArray,在每个索引上调用 new,然后手动分配每个 int。这只是一个简化的 { 1, 2, 3 },但我有一个从不同函数获得的更复杂的数字集,使用 { } 表示法读起来要好得多。

编辑:该内部删除的失败是:

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

编辑2:因此,如果它是未定义的行为,并且没有像我最初认为的那样在堆上分配一个、两个、三个数组,那么如何做如下的事情:

int ** foo()
{
    int ** multiArray = new int*[3];
    for(int i = 0; i < 3; ++i)
    {
        multiArray[i] = new int[3];
    }
    multiArray[0] = { 1, 2, 3 }; // Fail "Too many initializer values" on 2
    multiArray[1] = { 4, 5, 6 }; // Fail
    multiArray[2] = { 7, 8, 9 }; // Fail
    return multiArray;
}

编辑3:不是重复的,因为我特别要求与问题中提供的答案不同的答案,以及我试图确定数组是在堆上还是在堆栈上完成的事实。在标记为重复的问题中,这两个问题都没有解决。事实上,我特别谈到了这个问题中投票最多的答案,说这还不够。

为了使用 {} 表示法在堆上分配数组(仅在 c++11 或更高版本中(

int *a = new int[4]{1,2,3,4};

所以这意味着为了在堆上分配一个多维数组:

int **b = new int*[2]{new int[2]{1,2}, new int[2]{3,4}};

Foo 函数应为:

int ** foo()
{
    int **multiArray = new int*[3]{new int[3]{1,2,3}, new int[3]{4,5,6}, new int[3]{7,8,9}};
    return multiArray;
}

如果你不能使用C ++ 11,那么就没有简单的方法可以做到这一点。您需要分配内存,然后用值填充它。

相关内容

  • 没有找到相关文章