【问题标题】:Dynamically allocated C array of strings动态分配的 C 字符串数组
【发布时间】:2011-10-21 18:43:22
【问题描述】:

我不清楚为什么会失败,以及为什么会失败:

std::string* s;
s = (std::string*)malloc(sizeof(std::string) * 10);
s[0] = "string0";
s[1] = "string1";
s[2] = "string2"; //Segmentation fault

分配给 s[0] - s[2] 的字符串的大小是多少,或者分配了多少空间都没有关系。 QStrings 也会发生同样的事情。我认为问题出在 std::string 包含一个内部指针这一事实,因此 sizeof() 只返回指针的大小,但鉴于 std::strings 的行为与其他值类似(=、== 等。 ) 我不明白为什么这里会导致失败。

另外,为了与其他代码兼容,我需要在这里使用 C 数组,而不是例如标准::向量。如果有的话,我正在寻找一种通用的解决方案(可以与 QString、QDateTime 等一起使用)。但我很高兴知道发生了什么。

编辑:投了反对票...这个问题有什么问题?我确实先环顾了一会儿(包括 SO),没有发现这个问题。

【问题讨论】:

  • 您确实应该使用new(或在这种情况下为new[])来动态分配对象。而且你不能标记这个 C,因为它是 C++。
  • 是的,C 中不允许使用 std。
  • @WTP 使用new动态分配到底是什么?
  • @Matt Phillips 在本例中为 std::string 对象。
  • @WTP 很公平,代码不是 C,但它是 C 表示和分配数组的方式,而不是例如。标准::向量。

标签: c++ arrays string pointers


【解决方案1】:

你不能malloc 一个类对象数组,因为这个函数不调用任何构造函数。你只是让内存充满了垃圾,然后你尝试将其重新解释为类对象数组。

C++ 对象数组使用new[] 分配。

至于与其他代码的兼容性,您可能可以使用std::vector,因为&vec[0] 为您提供了指向连续数组中第一个元素的指针。


如果您坚持使用mallocfree,那么您需要手动调用每个带有新位置的数组项的构造函数,并在释放之前手动调用每个析构函数。

【讨论】:

  • '因为 &vec[0] 给你一个指向连续数组中第一个元素的指针' - 如果向量的大小为零,不幸的是。
【解决方案2】:

问题在于 std::string 有一个必须调用的构造函数。

并不是说有一个字符串数组是个好主意,但如果你必须:

string* s = new string[10];

【讨论】:

    【解决方案3】:

    问题的出现是因为您不应该使用 malloc 为具有构造函数的类(如 std::string)分配空间,除非您真的、真的知道自己在做什么。用简单的方法做,用新的

    std::string* s;
    s = new std::string[10];
    s[0] = "string0";
    s[1] = "string1";
    s[2] = "string2";
    

    您的代码不起作用的技术原因是您没有构造任何字符串,因为您没有调用它们的构造函数,您所拥有的只是一块未初始化的内存。另一方面,new 确实在它分配的内存上调用 std::string 构造函数。

    【讨论】:

      【解决方案4】:

      使用 malloc,不会调用 std::string 的构造函数。这可能是原因。顺便说一句,为什么在使用 std::string 时使用 malloc 分配内存?是什么阻止您使用 new ?

      【讨论】:

      • 我正在编写模板代码,我想与双精度、整数等一起使用,对于那些我认为只使用数组最有效的人。没看到这个问题... :(
      • @Matt:特别是如果您使用模板,那么您通常不能使用任何非类型感知的 C 库函数。
      • @UncleBens 是的,看起来你已经搞定了,我要给线程多一点时间来“解决”然后关闭它。
      【解决方案5】:

      如前所述:

      You can not malloc an array of class objects, because this
      

      function 不调用任何构造函数。你只是让记忆充满 带有垃圾,然后您尝试将其重新解释为类数组 对象。

      如果您想 [ 作为解决方法 ] 这样做:

      char * s[10];

      for (int i=0; i

      strcpy(s[0], "string0");

      strcpy(s[1], "string1");

      strcpy(s[2], "string2");

      【讨论】:

        【解决方案6】:

        你可能想要的是一个字符串向量:

        std::vector<std::string> s(3);
        s[0] = "string0";
        s[1] = "string1";
        s[2] = "string2";
        

        另外,为了与其他代码兼容,我需要在这里使用 C 数组,而不是例如标准::向量

        您可以获得指向第一个元素的原始指针,以便与旧代码互操作:

        string* p = &s[0];
        

        【讨论】:

        • 他明确地说,不是 std::vector。
        猜你喜欢
        • 2013-03-09
        • 2015-07-14
        • 1970-01-01
        • 2020-12-09
        • 1970-01-01
        • 1970-01-01
        • 2015-03-09
        相关资源
        最近更新 更多