【问题标题】:Large array in C++ works, but why?C++ 中的大数组可以工作,但为什么呢?
【发布时间】:2023-01-12 06:31:51
【问题描述】:

为什么我可以编译运行这段代码?数组是不是太大了?内存是如何分配给这个数组的?

#include <iostream>
#define Nbig 10000000000000000
int main() {
int x[Nbig];
x[Nbig-1]=100;
    std::cout <<"x[Nbig-1]= "<< x[Nbig-1] <<"\n\n";
    return 0;
}

我认为当声明一个静态数组时,应该为其分配一块 RAM,当我分配一个值来表示 x[1000] 时,'x+1000*4' 地址处的内存字节(4 用于 int 和 x第一个元素的地址)应该表示值。我尝试使用谷歌搜索并阅读有关静态和动态分配、堆和堆栈、RAM 本身的内容,但没有在任何地方找到我的答案。可能有帮助的其他信息:我正在使用具有 32GB RAM 的 linux,并使用 gcc 编译代码。

【问题讨论】:

  • MSVC 它不会编译。在 GCC 中,使用 -O1 它只是完全删除数组并打印 100-O0 没有运行。
  • 此代码中没有静态数组。您缺少关键字 static
  • 你应该尝试输出sizeof(x) / sizeof(x[0]);。它是否等于您作为 #define 拥有的号码?
  • 我试过并得到了这个: sizeof(x[0])= 4 sizeof(x)= 40000000000000000 @PaulMcKenzie
  • 你能详细说明一下吗?即使数组是动态的(或其他),程序不应该仍然按照我解释的方式分配内存吗? @Elijay

标签: c++ arrays memory


【解决方案1】:

我认为当声明静态数组时,应该为其分配一大块 RAM

那是 C++ 实现的实现细节。您要求在语言级别上提供给定大小的数组。编译器必须以这样一种方式编译程序,即它的行为与语言指定使用数组的程序的行为相同。语言标准没有提及 RAM 或堆栈,并允许任意大小的数组达到实现定义的限制。编译器如何使用内存来提供程序的这种行为完全取决于编译器。如果它能弄清楚,例如不需要使用 RAM 来使程序的行为与规范等效,那么它不需要使用任何 RAM。由于您只使用数组的一个元素,显然没有必要为整个数组预留内存。

【讨论】:

    【解决方案2】:

    供参考

     int main() {
        int x[Nbig];
    

    尝试在堆栈上分配 x(它是函数 main 的本地并且未显式声明 static)。通常,堆栈的最大大小约为几兆字节,因此您的大小不适合。大多数编译器都知道这一点并且会拒绝编译它。如果它确实编译它几乎肯定会在运行时失败。

    在你的情况下,编译器无论如何都会优化整个事情,因为你只使用一个元素。

    如果您需要一个可以分配的编译时数组,则将其设为静态。像这样

    int main() {
        static int x[Nbig];
    

    或者

     int x[Nbig];
     int main() {
    

    (忽略您的#define 将被截断的事实)

    这将分配在固定大小的数据段

    【讨论】:

      【解决方案3】:

      如果自动持续时间对象的地址从未暴露给外部代码或以编译器无法完全跟踪的方式使用,并且如果编译器可以“理解”对对象所做的一切,则编译器不需要分配实际对象的存储。

      在这种情况下,某些编译器可能会发现数组中只有一个元素被读取,并且始终写入值 100,因此无需为数组分配任何存储空间。相反,任何读取数组的操作都可以替换为加载常量 100 的操作。

      【讨论】:

        【解决方案4】:

        C++ 将 10000000000000000 识别为 1874919424。 如果你想出错,那么你的代码将是:

        #include <iostream>
        #define Nbig 10000000000000000ll
        int main() {
        int x[Nbig];
        x[Nbig-1]=100;
            std::cout <<"x[Nbig-1]= "<< x[Nbig-1] <<"
        
        ";
            return 0;
        }
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-21
        • 1970-01-01
        • 2015-09-13
        • 2021-07-04
        • 1970-01-01
        相关资源
        最近更新 更多