【问题标题】:Own Object as Data in stl Multimap在stl Multimap中将自己的对象作为数据
【发布时间】:2009-08-27 10:27:46
【问题描述】:

我正在编写一个应用程序,我想将字符串存储为键并将自定义对象存储为值

multimap<string, owncreatedobject> mymap;

编译效果很好,但在使用 insert 函数时出现“分段错误” 在运行时。

mymap.insert(string,myobject); --> Segmentation Error

A已经添加了一个copyconstructor一个assignmentfunction(调用copyconstructor)

关于“分段错误”的任何想法?

【问题讨论】:

  • 您能否展示一些有关如何插入元素以及如何使用它们的代码?
  • 对象 *a; a= new Object(), a->value1 = a; a->值2 = b;插入(字符串 a,对象 b); (这里是错误)插入:void Object::insert(string, a, Object b) { mymm.insert(pair(a,b));多重映射定义在私有头文件中:multimap mymm;
  • 这还能编译吗?如果 a 是指向对象的指针 (object* a;) 那么你怎么能做 mymm.inserrt(pair(a,b));}
  • 插入错误...
  • 如果您可以编辑您的问题并发布可重现问题的完整示例代码,这将更加简单。也不要键入代码,只需从编辑器中复制粘贴即可。

标签: c++ stl map


【解决方案1】:

查看您为复制构造函数和赋值运算符实现添加的注释,我发现您的赋值运算符实现是错误的。基本上它不会复制任何东西,而是使用声明 Filter(f); ,您正在创建一个名为 f 的本地对象。你不能像那样调用复制构造函数。我建议你编写一个私有的复制方法,并在复制ctor和赋值运算符中使用它。

【讨论】:

    【解决方案2】:

    在过去的一个小时里,我一直在解决你的问题,我想我明白了。

    尝试在这段代码中使用一些东西:

    multimap<string,yourclass const*> mymap
    void addtomap(string s,yourclass const* c)
    {
       mymap.insert(pair<string, yourclass const*>(s,c));
    }
    ...`addtomap("abc",&z);
    

    在您给定的示例中,您尝试在没有迭代器的情况下插入。多图的 2 元素插入调用的第一个元素是迭代器。这就是您的分段错误的原因,也是应该使用 pair 的原因。

    【讨论】:

      【解决方案3】:

      我怀疑您的复制构造函数和/或赋值运算符实现有问题。

      如果行

      mymap.insert(std::make_pair(mystring,myobject));
      

      崩溃,很可能是在“myobject”上执行的某些方法导致了问题。在此代码行中,最有趣的函数是复制构造函数和/或赋值运算符。

      您说您已经添加了一个赋值运算符(它调用了复制构造函数),但这听起来很奇怪。通常情况正好相反。复制构造函数根据需要分配资源(即内存),然后调用赋值运算符。

      更新:阅读您的评论后,您的复制构造函数应如下所示:

      Filter::Filter( const Filter &rhs ) {
          // Apparently no resource acquisition like memory allocation is necessary,
          // so just assign the rhs value.
          *this = rhs;
      }
      

      这是赋值运算符。请注意它是如何复制这些值的。您可能根本不需要赋值运算符(或复制构造函数)实现,因为编译器合成的代码非常适合您的使用。

      Filter &Filter::operator=( const Filter &rhs ) {
          SrcNET = f.SrcNET;
          SrcPort = f.SrcPort;
          DstNET = f.DstNET;
          FlowLabel = f.FlowLabel;
          return *this;
      }
      

      【讨论】:

      • 标头:Filter& operator=(Filter const &f);过滤器(常量过滤器 &f); cpp: Filter& Filter::operator =(Filter const &f) { if(this != &f) { Filter(f); } 返回 *this; } Filter::Filter(const Filter &f) { SrcNET = f.SrcNET; SrcPort = f.SrcPort; DstNET = f.DstNET; DstPort = f.DstPort; FlowLabel = f.FlowLabel; }
      • 你的赋值运算符是假的。它根本不影响“这个”。查看我更新的回复,了解如何实现这两个功能。
      【解决方案4】:

      我假设您正在尝试调用接受多图的value_type插入 版本。在这种情况下,请记住多图的value_typestd::pair。然后,试试这个:

      
      mymap.insert(std::make_pair(mystring,myobject));
      

      编辑(在您的评论之后):您的赋值运算符包含错误。您创建了一个没有目的的临时服务。下面是使用 swap idiom 的实现建议。 (请注意,我不知道类成员的类型。假设它们是内置的,例如 int。)

      
      void Swap(Filter const& f) //Create a swap member function.
      {
        std::swap(SrcNET, f.SrcNET);
        std::swap(SrcPort, f.SrcPort);
        std::swap(DstNET, f.DstNET); 
        std::swap(DstPort, f.DstPort); 
        std::swap(FlowLabel, f.FlowLabel);   
      }
      
      Filter& Filter::operator =(Filter f)
      { 
        swap(f); //Swaps the copy created for parameter passing (pass-by-value) above.
        return *this;
      } 
      

      【讨论】:

      • 我试过了,但仍然出现分段错误 也许我必须为我的对象编写一个分配器?
      • 然后,请张贴一小部分相关的代码来重现问题。可能是复制构造函数、一般程序逻辑或其他错误。我不认为分配器是错误的原因。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 2010-11-08
      • 1970-01-01
      相关资源
      最近更新 更多