加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C的动态数组有时会导致崩溃

发布时间:2020-12-16 07:12:16 所属栏目:百科 来源:网络整理
导读:我写了一个简单的代码如下: 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 != el
我写了一个简单的代码如下:

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,45}.如果我在括号中包含一个大小

show(new int[4]{1,4);

然后它工作.所以我自然会认为,如果我用这种方式编写新的,我必须指定大小(尽管我认为给它一个初始化列表会暗示大小).但是,奇怪的是,当在show函数调用中设置断点并且我一步一步地通过调试器运行它时,程序正确地输出所有内容并在它应该的主端结束.如果我不使用调试器,它会在输出'{‘之后崩溃,或者输出整个事物“{1,45}”并且断言失败“Program:…”表达式:_CrtIsValidHeapPointer( pUserData)……“

我很想知道它为什么会这样.另外,我在Windows 8上使用Visual Studio.

编辑:我正在使用namepsace标准.请不要评论使用命名空间或如何更好地编写此代码.我对这个问题的原因完全感兴趣.

解决方法

编辑回复评论中的其他问题.

要快,是的,它仍然会“指针”,当你添加4时,它会用clang和gcc编译.

然而,有几件事情正在发生,我最初的答案是简化.问题是你的表达式一开始并不是很好,所以不清楚它应该评估什么或类型应该是什么.考虑

If type is an array type,all dimensions other than the first must be specified as positive integral constant expression (until C++14)converted constant expression of type std::size_t (since C++14),but the first dimension may be any expression convertible to std::size_t.

资料来源:http://en.cppreference.com/w/cpp/language/new

正如它所说,无论哪种方式,括号中都必须有一个表达式.这使得很难说表达式是否仍将评估为指针.一个结构良好的新表达式确实会对指针进行求值,无论它有多少维度,即使它没有.当我在这里说指针时,我严格意味着表示,而不是类型.

重点是,至少“内部”新的类型根据您拥有的维度而有所不同.所以,不管你这样做

new int
new int[6]
new int[12][14]

表示是相同的(指针),但新看到的类型在每种情况下都是不同的.编译器能够响应新的不同类型(通过类比函数重载来思考).特别是,当类型是数组类型时,可以使用包含多个元素的支撑初始化列表初始化新内存.

我最好的猜测是,因为VS接受没有表达式的括号,所以它为单个int或int [0]分配内存.在前一种情况下,它错误地允许你支持初始化它就好像它是一个数组类型,而在后一种情况下,分配的内存无论如何都不够.然后你的主要编写了一个堆保护器,它可以在调试模式下捕获这种东西.当在主程序结束或程序终止时检查时,您看到了症状.输出中的薄脆度是由于不同的堆布局或由于输出流中的缓冲造成的.

原始答案

您的新表达式(如果格式正确)将具有标量类型,这意味着结果是“单个值”.该单个值是指向整数的指针,特别是指您尝试创建的数组开头的整数.这就是“动态数组”在C中的表示方式.类型系统不“知道”它们的大小.

您正尝试使用4个值的初始化列表初始化此单个指针值.这应该不起作用.我不确定这应该编译.它肯定没有用clang或gcc编译,我很惊讶它在Visual Studio中有效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读