c/c++语言开发共享声明具有0个元素的数组仍然可以存储值

我知道使用负面索引只是纯粹的运气。 但出于好奇,我尝试了这个。 我知道你可以声明array [0]; 就像malloc(0); 是合法的。 但是为什么我可以在array [0]中存储一个值?

#include  #include  int main(void) { int i; int array[0]; array[0] = 5; printf("%dn",array[0]); getch(); } 

    这样一个0大小的数组是标准C中的约束违规,你编译器不应该让你逃脱这个而不给你一个诊断。 如果它没有告诉你什么,那必须是你的编译器供应商添加到其C语言的扩展。

    不要依赖这样的扩展。

    无论您是否声明大小为0的数组,C都没有对数组或指针访问进行强制绑定检查。 但是,如果在编译时已知超出边界,那么一个好的现代编译器仍应该给出警告。

    您正在访问未定义或由其他内容使用的内存空间。 这段代码最终会搞砸了,因为在你使用malloc之前你不知道数组的存在。 您创建了一个大小为零的数组。 C会让你在任何地方写下你想要的任何地方。 禁止操作系统干扰。 “array”是指向数组的指针,它有一些任意值。 编译器不知道在使用它时应该为数组的第零个元素保留该内存空间。

    C假设(你可以)你知道你在做什么。 零长度数组仍然具有地址(但该地址可以很容易地与其他大小的地址共享)。 当你索引到那个数组时,你只是修改你正在使用的内存位置,而不用担心还有什么使用你最终得到的地址 – 通过写入,你很容易造成巨大的(并且很难调试)问题。

    就像Vikdor在评论中说的那样,你写的是一个不为你保留的记忆位置。 这可能导致严重且难以调试的问题所以我建议你永远不要这样做,但这是它的工作原理:

    当你声明一个大小为0 int array[0]int array[0] ,编译器会将名称’array’与一个内存位置相关联。 我们为这个例子说100。 但是因为数组的大小是0,所以没有字节属于数组,因此字节100,101等也可能被分配给其他变量。

    当你说array[0] = 5你将数字5写入字节100,101,102和103,因为int是4个字节长。 然后你可以使用从位置100开始读取4个字节的数组[0]来读取该数字。

    当从100开始的空间被赋予某个其他变量时会出现一个问题,因为它可能会覆盖数组[0]并且它看起来好像数组[0]已经无缘无故地改变了(这是你将花费大量令人沮丧的时间的地方)调试)

    请记住,int array [0]就像int * array。 数组的名称只是一个指针。

     int array[0]; 

    是无效的C代码。它是非标准的符合。 您的代码编译干净,因为它使用特定编译器的扩展

    参考:
    C99标准:6.7.5.2数组声明符
    第1段:

    除了可选的类型限定符和关键字static之外,[和]可以分隔表达式或* 。 如果它们分隔表达式(指定数组的大小),则表达式应具有整数类型。 如果表达式是常量表达式,则其值应大于零 。 元素类型不应是不完整或函数类型。 可选的类型限定符和关键字static应仅出现在具有数组类型的函数参数的声明中,然后仅出现在最外层的数组类型派生中。


    为什么它似乎有效?

    假设您的编译器实现允许零长度数组:

     array[0] = 5; 

    仍然有效,因为此代码语句导致未定义的行为
    它写入不属于数组的内存区域,从而覆盖已分配内存的边界。 幸运的是,它的工作原理是因为某些其他实体可能没有使用内存。 从技术上讲,它仍然是一种未定义的行为。

      以上就是c/c++开发分享声明具有0个元素的数组仍然可以存储值相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/545765.html

      (0)
      上一篇 2021年1月10日
      下一篇 2021年1月10日

      精彩推荐