Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将向量更改为数组并且必须使用指针-errormessage会说什么?C++;_C++_Arrays_Pointers_Vector - Fatal编程技术网

C++ 将向量更改为数组并且必须使用指针-errormessage会说什么?C++;

C++ 将向量更改为数组并且必须使用指针-errormessage会说什么?C++;,c++,arrays,pointers,vector,C++,Arrays,Pointers,Vector,在我的家庭作业中,我应该将向量从registry类更改为数组,并在BankVector类中定义它。我这样做了,编译器中的错误消息真的是。。。令人困惑我是新来的指针,所以我真的很困惑。错在哪里?或者是错误,哈哈,请帮帮忙 #include <iostream> #include <string> #include <array> #include <fstream> using namespace std; class Bankaccount{

在我的家庭作业中,我应该将向量从registry类更改为数组,并在BankVector类中定义它。我这样做了,编译器中的错误消息真的是。。。令人困惑我是新来的指针,所以我真的很困惑。错在哪里?或者是错误,哈哈,请帮帮忙

#include <iostream>
#include <string>
#include <array>
#include <fstream>
using namespace std; 

class Bankaccount{

  private: 
    string accName; 
    double balance;  
    char type;

  public:
    Bankaccount(); 
    Bankaccount(string name, char credit);
    string getName(); 
    double getBalance(); 
    void setBalance(double transferMoney); 
    char getCredit(); 

}; 

Bankaccount::Bankaccount(){
  accName = " ";
  balance = 0; 
  type = 'n'; 
}

Bankaccount::Bankaccount(string name, char credit){
  accName = name; 
  balance = 0; 
  type = credit;
}

string Bankaccount::getName(){
  return accName; 
}

double Bankaccount::getBalance(){
  return balance; 
}

void Bankaccount::setBalance(double transferMoney){
  balance += transferMoney; 
}

char Bankaccount::getCredit(){
  return type;
}



class BankVector {

  private:
        Bankaccount* entries;
        unsigned int usedCapacity;      
        unsigned int maxCapacity;

    public:
        BankVector();
        ~BankVector();
        unsigned int size() const;
        Bankaccount& at(unsigned int index) const;
        void push_back(Bankaccount a);
        void erase(unsigned int index);

        class IndexError:public exception{

          const char* what() const throw(){ 
            return "error: Index out of range";
          }
    };

};

BankVector::BankVector(){
    entries = new Bankaccount;
    usedCapacity = 0; 
  maxCapacity = 0; 
}

BankVector::~BankVector(){
     delete[] entries; 
}

unsigned int BankVector::size() const{
    return usedCapacity;
}

Bankaccount& BankVector::at(unsigned int index) const{
  if(index > usedCapacity){
    throw IndexError();
  } else {
    return entries[index];
  }
}

void BankVector::push_back(Bankaccount a){
    if(usedCapacity == maxCapacity){
      Bankaccount* tmp = new Bankaccount[maxCapacity + 1];
    for(int i = 0; i < maxCapacity; i++){
      tmp[i] = entries[i];
    }
    delete entries; 
    for(int i = 0; i < maxCapacity; i++){
     entries[i] = tmp[i];
    }
    delete tmp; 
    entries[maxCapacity] = a; 
    } else {
      entries[usedCapacity + 1] = a;  
    }
}

void BankVector::erase(unsigned int index){
    if(index >= 0 && index < usedCapacity){
        for(int i = index; i < usedCapacity - 1; i++){
            entries[i] = entries[i + 1]; 
        }
    usedCapacity = usedCapacity - 1; 
    } else{
      throw IndexError(); 
    }
}


class Registry{
  public: 
    void addAcc(string name, char isCredit); 
    void removeAcc(string name); 
    void transaction(string name, double transMoney); 
    bool checkDupl(string name); 
    double checkBalance(string name);
    char checkCreditType(string name); 
    void print();

  private: 
    BankVector accountlist; 
    int i; 
    double balance = 0;
    char type; 

}; 

void Registry:: addAcc(string name, char isCredit){
  Bankaccount newAcc(name, isCredit); 
  accountlist.push_back(newAcc); 
}

void Registry::removeAcc(string name){
  for(i = 0; i < accountlist.size(); i++){
    if(accountlist.at(i).getName() == name){
      accountlist.erase(i); 
    }
  }
}

void Registry::transaction(string name, double transMoney){
  for(i = 0; i < accountlist.size(); i++){
    if(accountlist.at(i).getName() == name){
      accountlist.at(i).setBalance(transMoney); 
    }
  }
}

bool Registry::checkDupl(string name){
  for(i = 0; i < accountlist.size(); i++){
    if(accountlist.at(i).getName() == name){
      return true; 
    }
  }
  return false; 
}

double Registry::checkBalance(string name){
    for(i = 0; i < accountlist.size(); i++){
      if(accountlist.at(i).getName() == name){
        balance = accountlist.at(i).getBalance();
      }
    }
  return balance;
}

char Registry::checkCreditType(string name){
  for(i = 0; i < accountlist.size(); i++){
      if(accountlist.at(i).getName() == name){
        type = accountlist.at(i).getCredit();
      }
    }
  return type;
}

void Registry::print(){
  for(i = 0; i < accountlist.size(); i++){
    if(accountlist.at(i).getBalance() >= 0){
      cout << accountlist.at(i).getName() << " owns " << accountlist.at(i).getBalance() << " euros" << endl; 
    } else if(accountlist.at(i).getBalance() < 0){
      cout << accountlist.at(i).getName() << " owes " << accountlist.at(i).getBalance() << " euros" << endl; 
    }
  }
}


int main(){
  Registry account;
  ifstream inFS; 
  string file, command, fileName;
  char creditType; 
  double moneyVal = 0; 
  int i = 0; 

  cout << "Enter the name of the records file: ";
  cin >> file; 

  inFS.open(file); 
  if(!inFS.is_open()){
    cout << "Could not open file " << file;
    return 0;
  }

  while(!inFS.eof()){
    i++;

    try{

      inFS >> command >> fileName; 

      if(command == "c"){
        inFS >> creditType;
        if(account.checkDupl(fileName) == true){
          throw runtime_error(": account already exists"); 
        } else {
          account.addAcc(fileName, creditType); 
        }
      }

      if(command == "r"){
        if(account.checkDupl(fileName) == false){
          throw runtime_error(": account does not exist");
        } else if(account.checkDupl(fileName) == true){
          if(account.checkBalance(fileName) >= 0){
            account.removeAcc(fileName);
          } else if(account.checkBalance(fileName) < 0){
            throw runtime_error(": account holds negative balance"); 
          }
        }
      }

      if(command == "t"){
        inFS >> moneyVal;
        if(account.checkDupl(fileName) == true){
          if((account.checkBalance(fileName) + moneyVal) >= 0){
            account.transaction(fileName, moneyVal);  
          } else if((account.checkBalance(fileName) + moneyVal) < 0){
            if(account.checkCreditType(fileName) == 'y'){
              account.transaction(fileName, moneyVal);  
            } else if(account.checkCreditType(fileName) == 'n'){
              throw runtime_error(": account cannot hold negative balance"); 
            }
          }
        }else{
          throw runtime_error(": account does not exist");
        }
      }  
    }

    catch(runtime_error& excpt){
      cout << "error on line " << to_string(i) << excpt.what() << endl; 
    }
  }

  cout<< endl; 
  account.print();

  return 0; 
}

让我们来分析一下您的
push_back
功能:

Bankaccount* tmp = new Bankaccount[maxCapacity + 1];
for(int i = 0; i < maxCapacity; i++){
    tmp[i] = entries[i];
}
好的,所以您不需要旧的数组,但是正如注释部分中已经强调的那样,您必须使用
delete[]条目因为它被分配了
new[]

for(int i = 0; i < maxCapacity; i++){
    entries[i] = tmp[i];
}
不!您不仅应该使用
delete[]
,而且不想这样做。刚刚销毁了阵列的最后一个剩余副本。现在你的数据在哪里?拆下这条线

entries[maxCapacity] = a; 
是的,它可以正常工作,但您忘记了一件事:
maxCapacity
应该在调整阵列大小时增加(或者至少在某个地方)。这一行在技术上是正确的,但在语义上是错误的。您还有另一个变量
usedCapacity
,它告诉您在哪里存储数据。理论上,每次调整大小时,您都应该将
maxCapacity
增加一个系数,这意味着它通常不会指向下一个空闲插槽。所以你应该这样做:

    // Better approach...
    entries[usedCapacity] = a;
    ++usedCapacity;
    ++maxCapacity;  // <- this line should actually go earlier when you resize
//更好的方法。。。
条目[usedCapacity]=a;
++使用容量;

++最大容量;// 您的
BankVector
课程中有几个错误。为了清晰起见,这里有一个经过清理的(希望是)正确的版本,内联了成员方法

class BankVector {
    Bankaccount* entries = nullptr;    // provide default initialisers
    unsigned int usedCapacity = 0;      
    unsigned int maxCapacity = 0;

    void grow()                        // double maxCapacity
    {
        maxCapacity = maxCapacity? 2*maxCapacity : 1;
        Bankaccount*tmp = new Bankaccount[maxCapacity];
        for(unsigned int i=0; i!=usedCapacity; ++i)
            tmp[i] = entries[i];
        delete[] entries;
        entries = tmp;
    }

  public:
    BankVector() = default;            // use default initialisers

    ~BankVector()
    { delete[] entries; }

    unsigned int size() const
    { return usedCapacity; }

    unsigned int capacity() const
    { return maxCapacity; }

    Bankaccount const& at(unsigned int index) const   // const access
    {
        if(index >= size())
            throw std::range_error("BankVector::at(): index=" +
                std::to_string(index) + " >= size()=" + std::to_string(size()));
        return entries[index];
    }

    Bankaccount & at(unsigned int index)   // non-const access
    {
        if(index >= size())
            throw std::range_error("BankVector::at(): index=" +
                std::to_string(index) + " >= size()=" + std::to_string(size()));
        return entries[index];
    }

    void push_back(Bankaccount const&a)
    {
        if(size() >= capacity())
            grow();
        entries[usedCapacity++] = a;
    }

    void remove(unsigned int index)    // fast but not order-preserving
    {
        if(index < usedCapacity)
            entries[index]=entries[--usedCapacity];
    }

    void erase(unsigned int index)     // order-preserving but slow
    {
        if(index >= size())
            throw std::range_error("BankVector::erase(): index=" +
                std::to_string(index) + " >= size()=" + std::to_string(size()));
        usedCapacity--;
        for(unsigned int i=index; i!=usedCapacity; ++i)
            entries[i] = entries[i+1];
    }
};
classbankvector{
Bankaccount*entries=nullptr;//提供默认初始值设定项
unsigned int usedCapacity=0;
无符号整数最大容量=0;
void grow()//最大容量加倍
{
maxCapacity=maxCapacity?2*maxCapacity:1;
银行账户*tmp=新银行账户[maxCapacity];
for(无符号整数i=0;i!=usedCapacity;++i)
tmp[i]=分录[i];
删除[]项;
条目=tmp;
}
公众:
BankVector()=默认;//使用默认初始值设定项
~BankVector()
{删除[]项;}
无符号整数大小()常量
{返回usedCapacity;}
无符号整数容量()常量
{返回最大容量;}
Bankaccount常量和at(无符号整数索引)常量//常量访问
{
如果(索引>=size())
抛出std::range_错误(“BankVector::at():index=”+
std::to_string(index)+“>=size()=”+std::to_string(size());
返回分录[索引];
}
Bankaccount&at(无符号整数索引)//非常量访问
{
如果(索引>=size())
抛出std::range_错误(“BankVector::at():index=”+
std::to_string(index)+“>=size()=”+std::to_string(size());
返回分录[索引];
}
无效回推(银行账户const&a)
{
如果(大小()>=容量())
增长();
条目[usedCapacity++]=a;
}
void remove(unsigned int index)//快速但不保留顺序
{
如果(索引<使用容量)
条目[索引]=条目[--usedCapacity];
}
void erase(unsigned int index)//保留顺序但速度较慢
{
如果(索引>=size())
抛出std::range_错误(“BankVector::erase():index=”+
std::to_string(index)+“>=size()=”+std::to_string(size());
使用容量--;
for(无符号整数i=index;i!=usedCapacity;++i)
分录[i]=分录[i+1];
}
};

它表示您尝试
删除
(或
删除[]
)以前未由
新建
(或
新建[]
)分配的指针,或者可能是
删除
两次。只需查看您的代码。。。分配给
new
的指针必须使用
delete
解除分配,分配给
new[]
的指针必须使用
delete[]
解除分配。没有混合和匹配。您应该在
BankVector
的默认构造函数中了解,您使用
new
分配内存,但析构函数使用
delete[]
取消分配内存。此外,由于没有要管理的数据,因此不需要在默认构造函数中分配内存。(
maxCapacity==usedCapacity==0
)顺便说一句。您应该使用构造函数初始化列表来初始化成员。这些赋值应该让您创建自己的向量类,以便您了解如何组合向量类的基本知识。此答案中存在语法和逻辑错误。一般来说,我认为最好是解释OP的错误并让他们纠正错误,而不是简单地为他们重写代码。
erase()
wt。。见鬼?
如果(size()>capacity())
如果这是真的,那么向量实现就被破坏了。我们要花更多的时间来更正这个答案,而不是更正原始代码。我投了反对票,因为我觉得答案没有用。它既不能回答问题,也不能教会OP任何东西。尽管您目前正在努力修复代码,但它仍然无法工作,甚至无法编译。最后,它添加了最新语言版本的语法,这些语法在原始代码中并不明显。所有这些只会让OP感到困惑,而不是教育他们。
entries[maxCapacity] = a; 
    // Better approach...
    entries[usedCapacity] = a;
    ++usedCapacity;
    ++maxCapacity;  // <- this line should actually go earlier when you resize
class BankVector {
    Bankaccount* entries = nullptr;    // provide default initialisers
    unsigned int usedCapacity = 0;      
    unsigned int maxCapacity = 0;

    void grow()                        // double maxCapacity
    {
        maxCapacity = maxCapacity? 2*maxCapacity : 1;
        Bankaccount*tmp = new Bankaccount[maxCapacity];
        for(unsigned int i=0; i!=usedCapacity; ++i)
            tmp[i] = entries[i];
        delete[] entries;
        entries = tmp;
    }

  public:
    BankVector() = default;            // use default initialisers

    ~BankVector()
    { delete[] entries; }

    unsigned int size() const
    { return usedCapacity; }

    unsigned int capacity() const
    { return maxCapacity; }

    Bankaccount const& at(unsigned int index) const   // const access
    {
        if(index >= size())
            throw std::range_error("BankVector::at(): index=" +
                std::to_string(index) + " >= size()=" + std::to_string(size()));
        return entries[index];
    }

    Bankaccount & at(unsigned int index)   // non-const access
    {
        if(index >= size())
            throw std::range_error("BankVector::at(): index=" +
                std::to_string(index) + " >= size()=" + std::to_string(size()));
        return entries[index];
    }

    void push_back(Bankaccount const&a)
    {
        if(size() >= capacity())
            grow();
        entries[usedCapacity++] = a;
    }

    void remove(unsigned int index)    // fast but not order-preserving
    {
        if(index < usedCapacity)
            entries[index]=entries[--usedCapacity];
    }

    void erase(unsigned int index)     // order-preserving but slow
    {
        if(index >= size())
            throw std::range_error("BankVector::erase(): index=" +
                std::to_string(index) + " >= size()=" + std::to_string(size()));
        usedCapacity--;
        for(unsigned int i=index; i!=usedCapacity; ++i)
            entries[i] = entries[i+1];
    }
};