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,那么就没有简单的方法可以做到这一点。您需要分配内存,然后用值填充它。