【问题标题】:How is it possible to have an array of strings in C++?如何在 C++ 中有一个字符串数组?
【发布时间】:2011-05-30 22:57:30
【问题描述】:

当您使用 array[i] 访问数组的元素时,我认为 C++ 会在内存中获取数组的起始位置并添加 i*sizeof(一个数组元素),然后取消引用该地址(或做一些等效的操作我刚才描述的)。但是,在我看来,如果你有一个字符串数组(std::string),每个元素的大小可能会根据字符串中的字符数而有所不同,所以肯定有其他事情发生。

另外,据我了解,数组元素存储在连续内存中。如果您将字符串存储在连续的内存中,然后将更多字符附加到其中一个,则所有后续字符串都必须移动。

有人可以向我解释这是如何工作的吗?

【问题讨论】:

  • 发布一些工作代码示例。 “字符数组”、“std::string 数组”和“[pointers to] 字符数组”等是有区别的。
  • 当我说字符串时,我的意思是 std::string,而不是 char*。
  • @pst: 没见过以前使用的短语“stdstr”。很有趣。
  • 将标题中的“why”改为“how”;巧妙地改变了问题的含义。
  • 实际上,我一直在争论自己是使用“为什么”还是“如何”。

标签: c++ arrays string


【解决方案1】:

字符串大小是恒定的,但它(在某种程度上)有一个指针指向一些非恒定大小的数据。

指针大小是恒定的,指针大小不是。

【讨论】:

    【解决方案2】:

    std::strings 是对象。一个std::string 的大小与另一个std::string 的大小相同。它们通过动态分配间接“包含”它们的数据,这不会影响拥有对象的大小。

    同样,如果你指的是 C 风格的字符串,你实际上只会传递 char*(或 pointers-to-char)。指针的大小始终相同,无论它们指向的内存块的长度如何。

    【讨论】:

    • 我认为重要的是要注意,因为指针的大小很重要,这也意味着可以有像 char ** 这样的东西,就像你在 main(int argc, char ** argv),并迭代这些 char 指针以获取实际的 char 字符串。
    • @MikeBantegui:是的,这是指向 C 风格字符串数组中第一个元素的指针。这就是我在第二段中所说的。这里真正需要注意的是char*[N]char[N][M]相同。
    【解决方案3】:

    std::stringchar* 的包装器,而不是数组。数组可以有不同的大小,是的,但是char*s 是指针并且具有恒定的大小。 std::string 封装的char* 指向动态分配的内存。这就是为什么sizeof(std::string) 无论字符串增长多大都会返回相同的大小。

    【讨论】:

    • 它们不必是 4 或 8 个字节。
    【解决方案4】:

    如果您指的是 C++ 类型 std::string,则字符串数组的每个元素都占用相同数量的内存。但是,每个字符串都可能包含一个指针,指向内存中不同长度的不同位置,它实际存储字符串的位置。

    要查看示例(示例代码),请想象std::string 类是这样的:

    struct string
    {
      size_t length;
      const char* data;
      // other members..
    };
    

    请注意结构大小始终相同(size_t 和指针),但指向的内存(存储实际字符串的位置)可能不同。

    【讨论】:

      【解决方案5】:

      字符串对象有一个大小,它会根据您的实现编译器等而有所不同。您对 c++ 处理数组的人的评估是正确的,但忽略了指针数据。其内部的字符串类有一个指向一些堆数据的指针,这些堆数据可以是任意大小,但指向该数据的指针是固定大小的。因此,在字符串的数据布局中,编译器有一种方法可以创建具有非固定表示数据的统一对象。

      【讨论】:

        【解决方案6】:

        由于字符串是字符指针,因此字符串数组是(char *) 的数组——(char *) 指针的连续向量。修改字符串会修改每个元素指向的内存。现在,如果你声明它是静态分配的:

        char foo[10][10];
        

        那么就内存布局而言,它与

        没有区别
        char foo2[100];
        

        并且有可能通过写入超过声明的大小来破坏内存;这是人们应该使用std::string 而不是 C 风格的字符串的原因之一,这可能是 C 是一种糟糕的应用程序编程语言的最好例子。 (std::string 的数组将是一个对象数组,每个对象都将有一个 (char *) 存储在您不需要担心的某个地方 - std::string 为您完成,而且更可靠。 )

        【讨论】:

          【解决方案7】:

          这就是你在代码中的做法......

          const int ARRSIZE = 5;
          string arrayOfStr[ARRSIZE] = {"one", "two", "three"};
          
          for (int i = 0; i < ARRSIZE; ++i)
          {                 
              cout << arrayOfStr[i] << endl;                  
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-07
            • 2011-11-29
            • 2012-08-15
            • 1970-01-01
            • 1970-01-01
            • 2020-05-18
            • 2022-01-04
            相关资源
            最近更新 更多