我如何处理这个C++;多重地图问题? 我是C++初学者,我在一个简单的程序上遇到了一个让我难堪的问题…基本上,我创建了一个多重映射,它接受字符串person name的一部分和指向person对象的指针

我如何处理这个C++;多重地图问题? 我是C++初学者,我在一个简单的程序上遇到了一个让我难堪的问题…基本上,我创建了一个多重映射,它接受字符串person name的一部分和指向person对象的指针,c++,c++11,pointers,C++,C++11,Pointers,因此,我使用的第一个函数是“Add()”函数。我基本上是用名字和年龄构造一个新人,然后设置一个指向该对象的指针。然后我将名称和对象作为一对插入到多重映射中 运行find()函数时会出现问题。。。我的输出只给了我一个有效的名字,但对于我的年龄,我得到的似乎是一个截断的内存地址或一个随机数?因为我是一个初学者,我很确定我在做一些非常简单但非常愚蠢的事情。我认为您不需要运行代码,因为它非常简单。感谢所有的帮助。谢谢大家! 我的可运行文件: #包括“Person.h” #包括 使用名称空间std; 多重

因此,我使用的第一个函数是“Add()”函数。我基本上是用名字和年龄构造一个新人,然后设置一个指向该对象的指针。然后我将名称和对象作为一对插入到多重映射中

运行find()函数时会出现问题。。。我的输出只给了我一个有效的名字,但对于我的年龄,我得到的似乎是一个截断的内存地址或一个随机数?因为我是一个初学者,我很确定我在做一些非常简单但非常愚蠢的事情。我认为您不需要运行代码,因为它非常简单。感谢所有的帮助。谢谢大家!

我的可运行文件:
#包括“Person.h”
#包括
使用名称空间std;
多重地图;
迭代器计数器;
void add()
{
字符串名;
智力年龄;
姓名;
年龄;
人员生成人员(姓名、年龄);
//避免使用动态类指针进行内存优化。
//避免:Person*pointer=新的Person(姓名、年龄)。
Person*指针=&generatedPerson;
insert({name,pointer});
}
void find()
{
找到字符串;
找不到人;
for(counter=personMap.begin();counter!=personMap.end();counter++)
{
如果(计数器->第一个==personToBeFound)
{

大家好,@1201programalm的评论是绝对正确的,然而,我自己想,我该如何“拯救”这个程序(a)用最小的努力,(b)获得正确的版本,(c)非常接近原始版本

因此,这里有一个新的
main.cc
版本(
Person.h
Person.cc
无需更改):

#包括“Person.h”
#包括
使用名称空间std;
多重地图;
迭代器计数器;
void add()
{
字符串名;
智力年龄;
姓名;
年龄;
插入({姓名,新人(姓名,年龄)});
}
void find()
{
找到字符串;
找不到人;
for(counter=personMap.begin();counter!=personMap.end();counter++)
{
如果(计数器->第一个==personToBeFound)
{

您是否正在地图中存储指向局部变量的指针,因此当您稍后尝试访问它时,指向的对象已被销毁(当
add
返回时)从更高的层次来看,您可能应该在数据容器中存储值类型而不是指针,例如
class Person
。映射将变成std::multimap。评论2:在
std::vector
上使用
std::multimap
的好处是,按键进行的搜索具有
O(log(n))
time complexity。通过在映射上迭代,需要'O(n)`-explore std::multi_map::equal_range()@1201程序非常有帮助,但我想了解为什么会这样,以及未来如何解决此问题的最佳实践。从逻辑上讲,地图接受指向person对象的指针。为什么当我创建一个实际指针并指向person对象,然后将其输入地图时,它会断开?感谢您的帮助花点时间开始评论!我很感激!如果你能帮助的话,最好的做法是不要有一个指针容器。如果你不能避免指针,请使用
std::unique\u ptr
not
Person*
。你的答案在fixed add()中是有意义的方法,谢谢你。请你解释一下为什么我不应该只删除键而不是值。如果我一路删除重复项也没关系。只删除键而不是将键的值置零不是很好吗?@michaow!精彩的回答和解释!非常感谢你花时间解释所有这些是@micha@XOR不客气,很高兴我能为你做些贡献。顺便说一句,你可能想回到这个人的演示,当它涉及到
std::shared\u ptr
std::unique\u ptr
时,这通常是
C++11
中的方式。它在
中包含
#include "Person.h"
#include <map>
using namespace std;

multimap<string, Person*> personMap;
multimap<string, Person*>::iterator counter;


void add()
{
  string name;
  int age;
  cout << "Please enter the name of the person: ",  cin >> name;
  cout << "Please enter the age of the person: ", cin >> age;
  Person generatedPerson(name, age);

  // Avoid dynamic class pointers for memory optimization.
  // Avoided: Person* pointer = new Person(name, age).
  Person *pointer = &generatedPerson;
  personMap.insert({name, pointer});

}

void find()
{
  string personToBeFound;
  cout << "Who do you wish to find, friend: ", cin >> personToBeFound;


  for (counter = personMap.begin(); counter != personMap.end(); counter++)
  {
    if (counter->first == personToBeFound)
    {
      cout << "\nName: " << counter->first << " Age: " << counter->second->getAge() << endl;
    }
    else if (counter->first != personToBeFound)
    {
      cout << "Error 404, person does not exist..." << endl;
    }
  }
}

// Experimental....
int main(int argc, char* argv[])
{
  int menuChoice = -1;

  while (menuChoice != 0)
  {
    cout << "\nPlease enter: "
            "\n1 - to add a person "
            "\n2 - to find a person"
            "\n0 - to quit\n" << endl;
    cin >> menuChoice;
    switch(menuChoice)
    {
      case 1: add();
        break;
      case 2: find();
        break;
      case 0: menuChoice = 0;
    }
  }
}
#ifndef PERSON_H
#define PERSON_H

#include <string>
#include <vector>
#include <iostream>

class Person {
 public:
  // Constructors

  /**
   * Create a Person with the given name and age.
   *
   * @param name name of the person
   * @param age age of the person - defaults to 0
   */
  Person(const std::string& name, unsigned short age = 0);


  // No explicit destructor necessary


  // Mutators

  /**
   * Set the name attribute
   *
   * @param name name of the person
   */
  void setName(const std::string& name);

  /**
   * Set the age attribute
   *
   * @param age age of the person
   */
  void setAge(unsigned short age);

  /**
   * Increment the age attribute
   */
  void growOlder();

  /**
   * Add a person to our list of children
   *
   * @param child Person to add as a child
   */
  void addChild(const Person& child);


  // Accessors

  /**
   * @return the Person's name
   */
  const std::string& getName() const;

  /**
   * @return the Person's age
   */
  unsigned short getAge() const;

  /**
   * @return a list of this Person's children
   */
  const std::vector<const Person *>& getChildren() const;

  /**
   * Define the ostream's << operator as a friend of this class
   * to allow this object to be printed to an output stream
   *
   * @param output the stream to print to
   * @param p the Person to print
   *
   * @return the output stream printed to
   */
  friend std::ostream& operator<< (std::ostream& output, const Person& p);


 private:

  // 0-arg Constructor
  Person();

  // Private attributes
  std::string _name;
  unsigned short _age;
  std::vector<const Person *> _children;

}; // Person

#endif
#include "Person.h"

Person::Person(const std::string& name, unsigned short age) :
    _name(name) , _age(age) {
}


void Person::setName(const std::string& name) {
  _name = name;
}


void Person::setAge(unsigned short age) {
  _age = age;
}


void Person::growOlder() {
  _age++;
}


void Person::addChild(const Person& child) {
  _children.push_back(&child);
}


const std::string& Person::getName() const {
  return _name;
}


unsigned short Person::getAge() const {
  return _age;
}


const std::vector<const Person *>& Person::getChildren() const {
  return _children;
}


std::ostream& operator<< (std::ostream& output, const Person& aPerson) {
  // Print our attributes to the output stream
  return output << "Name: '" << aPerson._name << "', Age: " << aPerson._age;
}
#include "Person.h"
#include <map>

using namespace std;

multimap <string, Person *> personMap;
multimap <string, Person *>::iterator counter;


void add()
{
    string name;
    int    age;

    cout << "Please enter the name of the person: ", cin >> name;
    cout << "Please enter the age  of the person: ", cin >> age;

    personMap.insert({ name, new Person(name, age) });
}


void find()
{
    string personToBeFound;

    cout << "Who do you wish to find, friend: ", cin >> personToBeFound;

    for (counter = personMap.begin(); counter != personMap.end(); counter++)
    {
        if (counter->first == personToBeFound)
        {
            cout << "\nName: " << counter->first
                 <<   " Age: " << counter->second->getAge() << endl;
        }
        else
        {
            cout << "Error 404, person does not exist..." << endl;
        }
    }
}


int main(int argc, char* argv[])
{
    int    menuChoice = -1;
    while (menuChoice != 0)
    {
        cout << "\nPlease enter: "
            "\n1 - to add a person "
            "\n2 - to find a person"
            "\n0 - to quit\n" << endl;

        cin >> menuChoice;
        switch(menuChoice)
        {
        case 1:
            add();
            break;

        case 2:
            find();
            break;

        case 0:
            menuChoice = 0;
            break;
        }
    }

    // -- How to go about clearing the heap? --

    for (counter = personMap.begin(); counter != personMap.end(); counter++)
    {
        if (counter->second) {
            delete   counter->second;
            counter->second = nullptr;
        }
    }
}