【问题标题】:How do you initialise a dynamic array in C++?如何在 C++ 中初始化动态数组?
【发布时间】:2011-01-03 00:47:08
【问题描述】:

我如何实现这个静态数组初始化的动态等效:

char c[2] = {};  // Sets all members to '\0';

换句话说,创建一个动态数组,其中所有值都初始化为终止字符:

char* c = new char[length]; // how do i amend this? 

【问题讨论】:

  • 哇.. 这是一个很好的问题。很多人似乎不知道 std::fill_n。
  • 只是为了记录,我并不是完全不知道std::fill_n,只是我大多忽略它,只在必要时使用_n算法。那是当迭代器类型不支持operator+ 时,std::advance 可能效率低下。这些条件都不适用于指针。

标签: c++ arrays


【解决方案1】:
char* c = new char[length]();

【讨论】:

  • 我总是忘记这一点。不适用于任何其他价值,但提问者没有要求任何其他价值......
  • 哇,我以前从未见过。
  • 同样,从未见过;你能描述一下这里发生了什么吗?这叫什么?
  • 如何重新定义这个数组的大小?
  • @re3el:这个问题是关于 C++ 的。你可以问一个关于 C 的单独问题,答案是使用calloc
【解决方案2】:

两种方式:

char *c = new char[length];
std::fill(c, c + length, INITIAL_VALUE);
// just this once, since it's char, you could use memset

或者:

std::vector<char> c(length, INITIAL_VALUE);

在我的第二种方式中,默认的第二个参数已经是 0,所以在你的情况下它是不必要的:

std::vector<char> c(length);

[编辑:投票给 Fred 的答案,char* c = new char[length]();]

【讨论】:

  • 我是 cpp 新手,读到写 int n; cin&gt;&gt;n; int arr[n]; 是违反 cpp 标准的。 int n; cin&gt;&gt;n; std::vector&lt;char&gt; c(n); 是否正确遵循标准?只是想知道!!
  • @jay:是的,没关系。
  • 但是std::vector&lt;char&gt; c[n] 违反了标准。对吗?
【解决方案3】:

也许使用std::fill_n()

char* c = new char[length];
std::fill_n(c,length,0);

【讨论】:

    【解决方案4】:

    new-expression 的数组形式只接受一种形式的初始化器:空的()。顺便说一句,这与非动态初始化中的空 {} 具有相同的效果。


    以上适用于 C++11 之前的语言。从 C++11 开始,可以使用带有数组新表达式的统一初始化语法

    char* c = new char[length]{};
    char* d = new char[length]{ 'a', 'b', 'c' };
    

    【讨论】:

      【解决方案5】:

      C++ 没有特定的功能可以做到这一点。但是,如果您使用 std::vector 而不是数组(您可能应该这样做),那么您可以指定一个值来初始化向量。

      std::vector <char> v( 100, 42 );
      

      创建一个大小为 100 的向量,所有值都初始化为 42。

      【讨论】:

        【解决方案6】:

        从 c++11 开始我们可以使用list initialization:

        char* c = new char[length]{};
        

        对于聚合类型,则执行aggregate initialization,效果与char c[2] = {};相同。

        【讨论】:

          【解决方案7】:

          你不能轻易做到这一点。你可以这样做:

          char* c = new char[length];
          memset(c, 0, length);
          

          或者,您可以重载 new 运算符:

          void *operator new(size_t size, bool nullify)
          {
              void *buf = malloc(size);
          
              if (!buf) {
                       // Handle this
              }
          
              memset(buf, '\0', size);
          
              return buf;
          }
          

          那么你就可以做到:

          char* c = new(true) char[length];
          

          同时

          char* c = new char[length];
          

          将保持旧的行为。 (注意,如果您希望所有 news 将他们创建的内容归零,您可以使用上面相同的方法,但去掉 bool nullify 部分)。

          请注意,如果您选择第二条路径,您应该重载标准的 new 运算符(没有 bool 的那个)和 delete 运算符。这是因为在这里您使用的是malloc(),而标准规定malloc() + delete 操作是未定义的。所以你必须重载delete才能使用free(),而普通的new才能使用malloc()

          在实践中,尽管所有实现都在内部使用 malloc()/free(),所以即使你不这样做也很可能不会遇到任何问题(除了语言律师对你大喊大叫)

          【讨论】:

          • 但是...可以看到std::fill / std::fill_n
          • 护目镜......他们什么都不做
          • 可能是因为这是解决问题的一种奇怪方法。更规范的解决方案是使用fill_nmemset 是原始的,fill_n 更通用,并且为了保持一致你会使用它),vector,或者上面的快捷方式到 0 答案。也就是说,您的 operator new 可能会有一些改进。而不是 malloc,只需使用常规的operator new:buf = ::operator new(size)。这应该会自动为您和new_handlers 处理所有异常。 (假设全局 operator new 正确)
          【解决方案8】:

          和许多海报的隐含评论 => 不要使用数组,使用向量。阵列的所有优点,没有任何缺点。另外,您还可以获得很多其他好东西

          如果你不了解 STL,请阅读 Josuttis 的 C++ 标准库和迈耶斯有效的 STL

          【讨论】:

            【解决方案9】:

            没有内部手段,AFAIK。用这个: memset(c, 0, 长度);

            【讨论】:

              【解决方案10】:

              你必须“手动”初始化它:

              char* c = new char[length];
              for(int i = 0;i<length;i++)
                  c[i]='\0';
              

              【讨论】:

              • 你可以这样做,但你不必这样做。关于 std::fill() 和 std::fill_n() 见上文。
              猜你喜欢
              • 2021-09-22
              • 1970-01-01
              • 2023-03-19
              • 2021-12-10
              • 2020-10-30
              • 1970-01-01
              • 2019-10-03
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多