【发布时间】:2015-07-27 22:26:52
【问题描述】:
我写了一个简单的代码如下:
void show(const int a[], unsigned elements);
int main()
{
show(new int[]{1, 2, 3, 45}, 4); //does not work
}
void show(const int a[], unsigned elements)
{
cout << "{ ";
for (int i = 0; i < elements; i++)
{
cout << a[i];
if (i != elements - 1)
cout << ",";
cout << " ";
}
cout << "}";
}
它应该只输出 { 1, 2, 3, 45 }。如果我在括号中包含尺寸
show(new int[4]{1, 2, 3, 45}, 4);
然后就可以了。所以很自然地,我会假设如果我以这种方式编写new,我必须指定大小(尽管我认为给它一个初始化列表会暗示大小)。但是,奇怪的是,当在 show 函数调用处设置断点并通过调试器逐步运行它时,程序正确输出所有内容并在 main 结束时终止,就像它应该的那样。如果我不使用调试器,它要么在输出 '{' 后崩溃,要么输出整个东西 "{ 1, 2, 3, 45 }" 和断言失败 "Program: ... "Expression: _CrtIsValidHeapPointer( pUserData) ... "
我很想知道它为什么会这样。另外,我在 Windows 8 上使用 Visual Studio。
编辑:我是using namepsace std。请不要评论使用命名空间或如何更好地编写此代码。我只对这个问题的原因感兴趣。
【问题讨论】:
-
第一个问题是你使用了一个“动态数组”,这样做
new很可能会导致内存泄漏。当您使用“动态数组”时,您的下一个想法应该是std::vector。 -
new T[]的返回值是T *,而不是T[]。这看起来像是具有 Java 背景的人会写的东西。 -
@JoachimPileborg 我明白这一点,我通常不会那样使用它,或者我至少会确保删除内存,但我只是想知道它为什么会这样。
-
@nabijaczleweli 我实际上确实有 java 背景,但据我了解,您可以将指向动态分配数组的第一个元素的指针作为参数传递,其中指定的类型是数组。此外,这不是问题的原因,因为如果我指定数组的大小,它就可以正常工作。
-
它的行为是这样的,因为
new int[]没有创建一个 4 int 的数组。从内存中,这样的代码甚至不应该根据标准编译,因为它正在使用由 4 个元素组成的初始化程序初始化不是 4 个元素的数组(new int []的结果)。
标签: c++ arrays memory dynamic crash