即使在向数组中添加更多具有值的元素后,数组的大小也保持不变

时间:2015-12-18 17:34:48

标签: c arrays sizeof

这只是我今天玩一些代码时所拾取的东西。我仍然是C新手,请善待。

下面的代码基本上是一个只有一个元素的数组,并检查它的大小和值(分别为4和0)。然后,它会在数组中创建新元素,并在再次检查数组大小之前为这些新元素分配值。

我发现阵列的大小不会增加。如果我从start开始创建包含5个元素的数组,则数组大小为20.如果我从start开始只创建1个元素并在之后添加其他4个元素,则数组大小保持为4但仍保留5个带有值的元素。

有人可以解释为什么会这样吗?这是一种在节省空间的同时为数组赋值的安全方法吗?或者这有什么问题吗?

我错过了什么吗?

如果我在错误的Stack Exchange论坛中发布此内容,请告知我,以便我可以将其删除并在其他地方提问,谢谢。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    int n = 5; 
    char temps[257] = "1 -2 -8 4 5\n"; 
    int arr[1] = {0};
    int c;   

printf("\n-- START of Test area --\n\n");

// sizeof arr = 4
printf("Initial sizeof(arr) = %d\n\n", sizeof(arr));

// Initial values of arr
printf("Value of arr[0] = %d\n", arr[0]);    // 0
printf("Value of arr[1] (no value assigned) = %d\n", arr[1]);    // random number
printf("Value of arr[2] (no value assigned) = %d\n\n", arr[2]);    // Random number

// sizeof arr = 4
printf("sizeof(arr) = %d\n\n", sizeof(arr));

// -- Creates new array elements and assigns values using temps 
sscanf(temps, "%d\n %d\n %d\n %d\n %d\n", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4]);    

printf("New array elements and values using temps\n\n");
printf("Value of arr[0] = %d\n", arr[0]);  // 1
printf("Value of arr[1] = %d\n", arr[1]);  // -2
printf("Value of arr[2] = %d\n", arr[2]);  // -8
printf("Value of arr[3] = %d\n", arr[3]);  // 4
printf("Value of arr[4] = %d\n", arr[4]);  // 5
printf("Value of arr[5] = %d\n\n", arr[5]);  // 0

// Sizeof array = 4
printf("sizeof(arr) = %d\n\n", sizeof(arr)); 

printf("\n-- END of Test area --\n\n");

    return 0;
}

3 个答案:

答案 0 :(得分:4)

声明数组后,您无法向其添加或减去任何元素,但可以修改 还有一件事是arr的大小为1,并且您正在某些语句中访问数组,例如

sscanf(temps, "%d\n %d\n %d\n %d\n %d\n", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4]); 

它调用未定义的行为。

答案 1 :(得分:3)

根据定义,数组是一块连续的内存。这意味着你只能告诉编译器一次数组的大小,它将为你的数组分配内存。

例如,如果编写int n[10];,编译器将在堆栈上保留10个整数值的内存(例如,每个int为8个字节)。

在这种情况下,n[9]是数组中的最后一个元素,因为n[0]是第一个元素。

让我更详细地解释一下: n实际上是数组第一个元素的内存地址。实际上n[0]n具有相同的内存地址。 如果你有int i;来表示你想要访问的数组的索引:

n[i]告诉编译器查看内存位置n + (i * sizeof(int));

编译器知道数组的类型,因此它知道在使用n[i];时如何计算适当的地址

现在如果i无效,编译器会提供一个可能包含垃圾的内存地址,或者您可能无权访问。如果你不小心,这会给你带来麻烦。

由于C在某种程度上是较低级别的语言,因此它不支持数组边界检查,并且它不会为您跟踪数组大小。这意味着你应该自己跟踪!否则你冒着未定义的行为的风险。

存在可以根据需要增长和缩小的其他数据结构(例如链表),但是那些通常使用&#34;免费商店&#34;或者&#34;堆内存&#34;并且工作方式与在堆栈上分配的内置数组不同。

答案 2 :(得分:1)

当您声明数组时,无法访问设置的维度的元素&gt; =。 设置的参数应该是常量并且在编译时间

中已知

例如

int n;
int arr[n]; // error: this is not known in compilation-time

int arr[2];
arr[5] = 6; // error: arr[5] doesn't actually exists!