如何使用内存?const char * const arr [] []的大小是多少? c ++

问题描述

我正在创建一个查找表,它将使用两个键/索引来访问const char *。

例如:

const char* const arr[2][3]={
   {"a","bb","ccc" },{"","","dddd"}
}

我担心的是这种表的内存使用情况,我计划制作的表的实际大小将为arr [〜60] [〜2000],其中包含大多数空元素。据我了解,这会创建一个指向const char *二维数组的常量指针。内存布局看起来如何,使用了多少内存?内存会简单地用作每个元素和每个元素内容的指针吗?

例如(包括终止符)2 * 3 * pointer_size +(2 + 3 + 4)+(1 + 1 + 5)

非常感谢您提供任何反馈意见。

侧面说明:我最初计划将unordered_map用于查找表,但是在使用一对整数作为键时,这需要创建自定义哈希。无论我当前的方法是否正确,我都想知道我上面想要做的事情的具体含义。

解决方法

如何使用内存

您永远不知道,直到程序被编译。仅检查汇编代码可能会给您任何答案。可以肯定的是,我通常在没有代码的情况下进行编译,并检查GNU size实用程序的输出,并进行比较以查看代码片段对可执行文件的影响。

const char * const arr [] []的大小是多少?

我相信您知道答案-就像您提供的示例一样,它是sizeof(const char *) * first_dimension * second_dimension个字节。

此的内存布局是什么样的

首先,显示的代码无效-[2][3]数组的初始化符太多。更正错误后,即。删除不需要的初始化程序(因为我懒得再画3个框),因此内存布局可能如下所示:

   const char *arr[2][3]
   +-------+------+-------+------+------+------+
   | 0x... |      |       |      |      |      |
   +-------+------+-------+------+------+------+
       |       |      |       |      |      |
       |       |      |       |      |      +----------->---+---+---+---+----+
       |       |      |       |      |                  | d | d | d | d | \0 |
       |       |      |       |      |                  +---+---+---+---+----+
       |       +---+  |       +------+-+
       |           |  |                |
       v---+----+  |  +---->---+---+---v----+
       | a | \0 |  |       | c | c | c | \0 |
       +---+----+  |       +---+---+---+----+
                   |
                   +-->---+---+----+
                       | b | b | \0 |
                       +---+---+----+
    

每个框代表一个元素,const char *arr[2][3]下方的每个框代表一个const char *指针,而在其他所有位置,每个框代表一个char字节。请注意,我在arr[1][0]的NUL字节上绘制了arr[1][1]"ccc"-编译器可能会优化并合并多个字符串文字。编译器也可能不会这样做-如上所述,仅检查生成的程序集会知道到底发生了什么。

请注意,如果数组不是可变的,则最好将其设置为const。在为裸机控制器进行编译时执行const char *const arr[2][3],这将允许编译器将整个阵列放置在闪存中,从而减少初始化bss和ram的使用。字符串文字应该放在只读部分,因为它们是不可变的。在c ++中,您还可以根据需要考虑添加constexpr(或consteval)。

但是,直到您检查装配时,您才知道。如果将arr的定义放在函数内,则编译器可能会决定在进入函数godbolt example时在堆栈上重新创建整个数组(还包括字符串文字)。不同的编译器优化选项起作用。

仅将内存用作指向每个元素和每个元素内容的指针吗?

好吧,通常是。