简体   繁体   English

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

[英]Size of array stays the same even after adding more elements with values to the array

this is just something I picked up while playing around with some code today. 这只是我今天在玩一些代码时学到的东西。 I am still a C newbie, please be kind. 我还是C新手,请客气。

The code below is basically taking an array with only one element and checking its size and value (4 and 0 respectively). 下面的代码基本上是使用只有一个元素的数组并检查其大小和值(分别为4和0)。 It then creates new elements in the array and assigns values to these new elements before checking the size of the array again. 然后,它在数组中创建新元素,并在再次检查数组大小之前为这些新元素分配值。

What i find is that the array does not increase in size. 我发现的是数组的大小没有增加。 If I create the array with 5 elements from start, the array size is 20. If i create only 1 element from start and add the other 4 later, the array size stays at 4 but still holds 5 elements with values. 如果我从头开始创建5个元素的数组,则数组大小为20。如果我从头开始仅创建1个元素并在以后添加其他4个元素,则数组大小保持为4,但仍包含5个带有值的元素。

Could somebody explain why this happens? 有人可以解释为什么会这样吗? Is this a safe way of assigning values to an array while saving space? 这是在节省空间的同时将值分配给数组的安全方法吗? Or is there something wrong with this? 或者这有什么问题吗?

Am i missing something? 我想念什么吗?

If I have posted this in the wrong Stack Exchange forum, please let me know so I can delete it and ask it somewhere else, thanks. 如果我在错误的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;
}

Once an array is declared you can't add or subtract any element to it, but can modify. 声明数组后,您将无法对其添加或减去任何元素,但可以进行修改。
One more thing is that arr is of size 1 and you are accessing array out of bound in some statements like 还有一件事是arr的大小为1并且您正在访问某些语句中的数组,例如

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

It invokes undefined behavior. 它调用未定义的行为。

An array by definition is a block of contiguous memory. 根据定义,数组是一块连续的内存。 That means you can only tell the compiler about the size of the array one time and it will allocate memory for your array. 这意味着您只能一次告诉编译器有关数组大小的信息,它将为数组分配内存。

For example if you write int n[10]; 例如,如果您编写int n[10]; the compiler will reserve memory on the stack for 10 integer values (for example 8 bytes for each int). 编译器将在堆栈上为10个整数值保留内存(例如,每个int为8个字节)。

In this case n[9] is the last element that your array holds, since n[0] is the first. 在这种情况下, n[9]是数组保留的最后一个元素,因为n[0]是第一个元素。

let me explain this in more detail: n is actually the memory address of the first element of the array. 让我更详细地解释一下: n实际上是数组第一个元素的内存地址。 in fact n[0] and n have the same memory address. 实际上, n[0]n具有相同的存储器地址。 if you have int i; 如果你有int i; to denote the index of array you like to access: 表示您要访问的数组的索引:

n[i] tells the compiler to look at memory location n + (i * sizeof(int)); n[i]告诉编译器查看内存位置n + (i * sizeof(int));

the compiler knows the type of array, so it knows how to calculate the appropriate address when you use n[i]; 编译器知道数组的类型,因此知道使用n[i];时如何计算适当的地址n[i];

now if i is not valid, the compiler will come up with a memory address that might contain garbage, or you may not have access to. 现在,如果i无效,编译器将提供一个可能包含垃圾的内存地址,或者您可能无权访问。 This will cause you problems if you are not careful. 如果您不小心,将会给您带来麻烦。

since C is somewhat of a lower level language, it does not support array bounds checking and it does not keep track of array size for you. 由于C某种程度上是一种较低级的语言,所以它不支持数组范围检查,也无法为您跟踪数组大小。 That means you should keep track of that yourself! 这意味着您应该自己跟踪它! or else you risk undefined behaviour. 否则您将面临不确定的行为风险。

There exist other data structures that can grow and shrink as required (such as linked list) but those usually use "the free store" or "heap memory" and work differently than a built in array that gets allocated on the stack. 还有其他数据结构可以根据需要增长和收缩(例如链表),但通常使用“免费存储”或“堆内存”的数据结构,其工作方式不同于在堆栈上分配的内置数组。

When you declare an array it's impossible to access an element >= of the dimension setted. 声明数组时,无法访问设置的维度> =的元素。 The argument setted should be constant and known in compilation-time 设置的参数应为常量,并且在编译时已知

For example 例如

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!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM