The array is static, but the array size isn't know until runtime. How is this possible?

三世轮回 提交于 2019-12-13 12:03:05

问题


This has been troubling me for a while. It goes to the heart of my (lack of) understanding of the difference between static and dynamic memory allocation. The following array is an ordinary static array, which should mean the memory is allocated during compile time, correct? Yet, I've set it up so that the user enters the array size at runtime.

#include <iostream>
using namespace std;

int main() {
  cout << "how many elements should the array hold? ";
  int arraySize;
  cin >> arraySize;

  int arr[arraySize];

  for (int i = 0; i < arraySize; ++i)
    arr[i] = i * 2;

  return 0;
}

Note that there are no new or delete operators in this program. It works fine in Xcode 4.2 (default Clang compiler) as well as my school's UNIX server (GCC 4.4.5). How does the compiler know how much memory to allocate for arr when the array is created at compile time? Is this just a fluke of my compiler, dangerous code that could corrupt other memory, or is this legit?


回答1:


This is a non-standard extension of your C++ compilers. Note that in C, unlike in C++, this is officially supported (i.e. standard-mandated behaviour) since C99. In C++, it is not supported because there's already a solution to the problem: Use std::vector instead of the array.

Not however that the array is not using static memory allocation (nor dynamic memory allocation), but automatic memory allocation. Automatic variables are automatically deallocated at the end of the function (the memory area where they are allocated is known as the stack, because the allocations and deallocations on it have stack semantics). To have the array use static memory allocation you would have to put static in front of the definition (note that variables in global or namespace scope always use static memory allocation, though). However, if you make the variable static, you'll find that the compiler doesn't allow to use a non-constant array size any more.

Note that std::vector stores its data with dynamic memory allocations instead. For that reason, you can also use a non-constant size even for static std::vectors.




回答2:


For an array (or any object) declared inside a function, the memory is allocated on entry to the function (typically on the stack) and deallocated when the function returns. The fact that the function happens to be main in this case doesn't affect that.

This:

cin >> arraySize;
int arr[arraySize];

is a "variable-length array" (VLA). The thing is, C++ doesn't support VLAs. C does, starting with the 1999 ISO C standard (C99), but it's not a feature that C++ has adopted.

Your compiler supports VLAs in C++ as an extension. Using them makes your code non-portable.

(One problem with VLAs is that there's no mechanism for detecting an allocation failure; if arraySize is too big, the program's behavior is undefined).

For gcc, compiling with -pedantic will produce a warning:

warning: ISO C++ forbids variable length array ‘arr’



回答3:


The generated code allocates arraySize bytes on the stack at runtime. Once the function returns, the stack unwinds, including "giving back" the bytes which were allocated on it for the array.

Using new and delete is for allocating space on the heap. The allocated memory lifetime on the heap is independent of any function or method scope - If you allocate space on it in a function, and the function returns, the memory is still allocated and valid.




回答4:


It's a Variable Length Array (supported only in C99 and not in C++). It is allocated on the stack at runtime.



来源:https://stackoverflow.com/questions/8861435/the-array-is-static-but-the-array-size-isnt-know-until-runtime-how-is-this-po

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!