为什么我无法在for循环中访问动态分配的内存?

Lee*_*wis 6 c++ polymorphism pointers

我为我的子类类型库存新的内存,它继承自基类工具,当我尝试访问我的数组的第二个元素时,它会抛出错误.当我的新数组大小为1时,情况很好

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

class Instrument{

public:
    virtual void display(){}
    virtual void output(){}
    virtual void readFile(){}
    virtual ~Instrument(){}
};
class Stock : 
    public Instrument{
public:
    Stock(){

    }
    virtual void input(){
        cout << "This is stock, please input its information: ";
        cin >> name >> bidPrice >> askPrice >> lastPrice >> issueExchange;
    }
    virtual void display(){
        cout <<"This is to display stock: "<< name << " "
            << bidPrice << " "
            << askPrice << " "
            << lastPrice << " "
            << issueExchange << " "
            << endl;
    }
    virtual void output(){
        ofstream myfile;
        myfile.open("Stock.txt", ios::out | ios::app);
        if (myfile.is_open()){
            myfile << "This is a stock: "
                << name << " "
                << bidPrice << " "
                << askPrice << " "
                << lastPrice << " "
                << issueExchange << " "
                << endl;
        }
        else cout << "Unable to open file";
    }
    virtual void readFile(){
        string line;
        ifstream myfile("Stock.txt");
        cout << "\nThis is file stored\n";
        if (myfile.is_open())
        {
            while (getline(myfile, line))
            {
                cout << line << '\n';
            }
            myfile.close();
        }
    }
    virtual ~Stock(){}
private:
    char name[13];
    double bidPrice;
    double askPrice;
    double lastPrice;
    int issueExchange;

};


int main(){

    const int N = 5;//it works fine if I use N=1;
    Instrument *pBase = NULL;
    pBase = new Stock[N];

    for (int i = 0; i < N; i++){
        pBase[i].input();// here throws an exception and ends the program
        pBase[i].display();
        pBase[i].output();
    }
    pBase[N - 1].readFile();
    delete[] pBase;

    system("pause");
    return 0;

} 
Run Code Online (Sandbox Code Playgroud)

Ben*_*igt 7

多态性和指针算法不会混合,因为数组中对象的排列取决于最大的派生大小,而多态性会丢失该信息.动态分配是一个红色的鲱鱼,你可以看到同样的问题:

Derived array[2];
Base* p = array;

printf("%p\n", &array[0]);
printf("%p\n", p);
printf("%p\n", &array[1]);
printf("%p\n", p + 1);

printf("%z\n", sizeof (array[0]));
printf("%z\n", sizeof (*p));
Run Code Online (Sandbox Code Playgroud)

请注意,使用的指针值array是向前移动sizeof (Derived),但指针算术使用p是向前移动sizeof (Base)而不是找到真实对象.

通常你会使用一个数组来修复它Base*,而不是单个Base*结合指针算法.

Base* pp[2];
for( auto& elem : array ) pp[&elem - array] = &elem;

printf("%p\n", &array[1]);
printf("%p\n", pp[1]);

// use (*pp[1]) or pp[1]->whatever
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用记住原始类型的对象:

Derived* allocated = new Derived[N];
std::function<Base& (int)> poly = [allocated](int i){ return allocated[i]; };
Run Code Online (Sandbox Code Playgroud)

并使用poly(i)而不是p[i]

但警告,你不能这样做,delete [] &poly(0);因为delete[]也不是多态的.

使用std::unique_ptr<Derived[]>std::bind,当访问者对象最终超出范围时,可以安排自动释放.

  • 虽然准确,这个答案有点缺乏解释,不是吗? (3认同)
  • @LightnessRacesinOrbit:您还可以使用指针数组,每个指针指向数组中的相应元素. (2认同)