int LA = {1,2,3,4,5}内存分配混乱c

我观察到为数组分配的内存似乎是动态的。

以下是我在本教程中找到的示例代码:

#include  main() { int LA[] = {1,3,5,7,8}; int item = 10, k = 3, n = 5; int i = 0, j = n; printf("The original array elements are :\n"); for(i = 0; i= k){ LA[j+1] = LA[j]; j = j - 1; } LA[k] = item; printf("The array elements after insertion :\n"); for(i = 0; i<n; i++) { printf("LA[%d] = %d \n", i, LA[i]); } } 

和样本输出:

 The original array elements are : LA[0]=1 LA[1]=3 LA[2]=5 LA[3]=7 LA[4]=8 The array elements after insertion : LA[0]=1 LA[1]=3 LA[2]=5 LA[3]=10 LA[4]=7 LA[5]=8 

它的工作原理我没有得到。

首先,对于没有显式大小定义并使用大括号括起初始化器初始化的数组的一般语句,大小将取决于初始化列表中的元素。 所以,对于你的arrays

  int LA[] = {1,3,5,7,8}; 

大小将是5 ,因为你有5个元素。

C使用基于0的数组索引,因此有效访问将为0到4。

在你的代码中

  LA[j+1] = LA[j]; 

试图访问索引6 ,( 5+1 )超出限制访问。 这会调用未定义的行为 。

具有UB的代码的输出不能以任何方式certificate。


也就是说,根据最新的C标准, main()在技​​术上是无效的签名。 您至少需要使用int main(void)来使代码符合托管环境。

代码有缓冲区溢出错误! C中的数组无法扩展! 在声明/定义它时,您需要分配足够的空间。

您可以通过在声明中提供大小来声明额外的空间:

 int LA[10] = {1,3,5,7,8}; 

LA现在可以容纳10个元素,索引0到9。

如果你想要更多的灵活性,你应该使用指针和malloc / calloc / realloc来分配内存。

注意:

复制中存在第二个错误。 循环开始一步太远了。

j从5开始并指定索引j+1 ,代码分配LA[6] ,这是第7个元素。 插入后只有6个元素。

我从这两个错误中得出的结论是,该教程既没有由经验丰富的C程序员编写也没有经过审核。

要添加其他答案,C / C ++不会对数组进行任何边界检查。

在这种情况下,您有一个堆栈分配的数组,因此只要您的索引不留下堆栈空间,运行时就不会出现“错误”。 但是,由于您要离开数组的边界,如果内存位置恰好位于分配的数组之后,您可能最终会更改也在堆栈中分配的其他变量的值。 这是缓冲区溢出的危险之一,并且可能在更复杂的程序中导致非常糟糕的事情发生。