插入指向向量的结构指针

时间:2021-05-20 06:00:14

标签: c++ vector struct

我正在尝试使用 vector 创建一个结构指针列表。我的结构包含一些字段,如

#include<stdio.h>
#include<stdlib.h>
#include<vector>
#define MAX 100

struct Student {
    char* name,
    *phoneNum,
    *address
};

我有一个实用函数可以帮助初始化结构指针

struct Student* newStudent() {
    struct Student* pStudent = NULL;
    pStudent = (struct Student*)malloc(sizeof(struct Student));
    pStudent->name = (char*)malloc(MAX * sizeof(char));
    pStudent->phoneNum = (char*)malloc(MAX * sizeof(char));
    pStudent->address = (char*)malloc(MAX * sizeof(char));
  
    return pStudent;
}

插入函数就像

void insert(vector<Student*> &listStudents, Student* pStudent) {
    printf("name: "); scanf("%s\n" , pStudent->name);
    printf("phone number: "); scanf("%s\n", pStudent->phoneNum);
    printf("address: "); scanf("%s\n", pStudent->address);
    listStudents.push_back(pStudent);
    printf("inserted OK!\n");
    printf("Size: %lu\n", listStudents.size());
}

和显示功能

void display(vector<Student*>& listStudents) {
    printf("total students: %lu\n", listStudents.size());
    for (int i = 0; i < listStudents.size(); i++) {
        printf("Student %d\n", i+1);
        printf("name: %s\n", listStudents[i]->name);
        printf("phone number: %s\n", listStudents[i]->phoneNum);
        printf("address %s\n", listStudents[i]->address);
    } 
}

这是我的主要功能

int main() {
   
   Student* pStudent = newStudent();
   vector<Student*> listStudents;
   while(true) {
        int op1;
        printf("\n1. input\n2. output\n3. search\n4. erase\n5. end\n");
        printf("option: "); 
        scanf("%d", &op1);
        switch(op1) {
            case 1:
                insert(listStudents, pStudent);
                break;
            case 2:
                display(listStudents);
                break;
            default:
                printf("invalid option!\n");
                break;
        }
    }
    
    free(pStudent);
}

当我尝试在每个字段中插入一些信息时。挺好的但是当我展示它时 出去。结果是重复的。例如:

insert

Student 1:
name: A
phone number: 010...
address: xyz

Student 2:
name: B 
phone number: 011...
address: zyz 

display 结果是

Student 1:
name: B 
phone number: 011...
address: zyz 

Student 2:
name: B 
phone number: 011...
address: zyz 

这是怎么回事??

2 个答案:

答案 0 :(得分:2)

你的问题是你有一个学生类的实例,你写了它。在 C++ 中,类通常具有值语义。你通常不管理自己的记忆。这是一个更惯用的实现:

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

class Student final {
 private:
  std::string m_name;
  std::string m_phoneNum;
  std::string m_address;

 public:
  Student(std::string name, std::string phoneNum, std::string address)
      : m_name(std::move(name)),
        m_phoneNum(std::move(phoneNum)),
        m_address(std::move(address)) {}

  auto& Name() const noexcept { return m_name; }

  auto& PhoneNumber() const noexcept { return m_phoneNum; }

  auto& Address() const noexcept { return m_address; }
};

Student GetStudent() {
  std::string name, num, addr;
  std::cout << "Name: ";
  std::cin >> name;
  std::cout << "Phone nnumber: ";
  std::cin >> num;
  std::cout << "Address: ";
  std::cin >> addr;
  Student st(std::move(name), std::move(num), std::move(addr));
  return st;
}

int main() {
  std::cin.exceptions(std::istream::failbit | std::istream::badbit);

  std::vector<Student> vec;
  vec.push_back(GetStudent());
  vec.push_back(GetStudent());
  vec.push_back(GetStudent());

  for (auto const& elm : vec) {
    std::cout << "Name: " << elm.Name() << "\nPhone: " << elm.PhoneNumber()
              << "\nAddress: " << elm.Address() << '\n';
  }
}

这也解决了许多其他错误:

  • 您的 scanf 调用可能会发生缓冲区溢出
  • lu 不是 size_t
  • 的正确说明符
  • 你泄露了字符串成员(全部)
  • nullptr 之后不检查 malloc
  • 您的代码不是异常安全的
  • printf 要么被显式刷新,要么在调用 '\n' 之前以 scanf 结束。

可能还有更多。

答案 1 :(得分:0)

正如@WhozCraig 在他的评论中提到的,您正在更改相同的结构指针。您必须每次分配不同的结构指针。你的主要功能应该是这样的,

int main() {
   vector<Student*> listStudents;
   while(true) {
        int op1;
        printf("\n1. input\n2. output\n3. search\n4. erase\n5. end\n");
        printf("option: "); 
        scanf("%d", &op1);
        switch(op1) {
            case 1: {
                Student* pStudent = newStudent();
                insert(listStudents, pStudent);
                break;
            }
            case 2:
                display(listStudents);
                break;
            default:
                printf("invalid option!\n");
                break;
        }
    }
    
    for (const auto& pointers: listStudents)
        free(pointers)
}

每次用户输入 1 时,您必须分配一个新的结构体指针。