<BadPtr> Ошибка в цикле

0

Я получаю ошибку BadPtr всякий раз, когда я достигаю этой точки в коде: Почему?

for(int i = 0; i < processTable.size(); i++)
        {
            data_entry test = *processTable.at(i).dataCurrent; //ERROR
            cout << test.text << "\n";
        }

Вот мой код:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>

using namespace std;

enum process_state { READY, RUNNING, WAITING };

struct data_entry {
    const char * text;
    int time;
};

struct process_entry
{
    int process;
    const data_entry * dataStart;
    const data_entry * dataEnd;
    const data_entry * dataCurrent;
    process_state state;
};

int _tmain(int argc, _TCHAR* argv[])
{
    vector<data_entry> dataTable;
    vector<process_entry> processTable;

    string line;
    ifstream myfile ("C:\\Users\\1162852\\Documents\\visual studio 2010\\Projects\\Project 1 (OS)\\Debug\\input.txt");
    if (myfile.is_open())
    {
        int processAmount = 0;

        while ( getline (myfile,line) )
        {
            if(line.find("START") != string::npos)
            {
                data_entry newEntry;
                newEntry.text = "START";
                newEntry.time = atoi(line.substr(6, 6).c_str());
                dataTable.push_back(newEntry);

                process_entry newProcessEntry;
                newProcessEntry.dataStart = &dataTable.at(dataTable.size() - 1);
                newProcessEntry.dataCurrent = &dataTable.at(dataTable.size() - 1);
                newProcessEntry.process = processAmount;
                processTable.push_back(newProcessEntry);

                processAmount += 1;
            }
            else if(line.find("END") != string::npos)
            {
                data_entry newEntry;
                newEntry.text = "END";
                newEntry.time = NULL;
                dataTable.push_back(newEntry);

                processTable.at(processTable.size() - 1).dataEnd = &dataTable.at(dataTable.size() - 1);
            }
            else if(line.find("RUN") != string::npos)
            {
                data_entry newEntry;
                newEntry.text = "RUN";
                newEntry.time = atoi(line.substr(4, 4).c_str());
                dataTable.push_back(newEntry);
            }
            else if(line.find("INPUT") != string::npos)
            {
                data_entry newEntry;
                newEntry.text = "INPUT";
                newEntry.time = atoi(line.substr(6, 6).c_str());
                dataTable.push_back(newEntry);
            }
            else if(line.find("SSD") != string::npos)
            {
                data_entry newEntry;
                newEntry.text = "SSD";
                newEntry.time = atoi(line.substr(4, 4).c_str());
                dataTable.push_back(newEntry);
            }
        }

        //reverse(dataTable.begin(),dataTable.end());
        /*for(int i = 0; i < dataTable.size(); i++)
        {
            cout << dataTable.at(i).text << "\n";
        }*/

        for(int i = 0; i < processTable.size(); i++)
        {
            data_entry test = *processTable.at(i).dataCurrent;
            cout << test.text << "\n";
        }
        myfile.close();
    }

    int test;
    cin >> test;
    return 0;
}
  • 0
    Пожалуйста, укажите ТОЧНУЮ ошибку, которую вы получаете при компиляции.
  • 0
    Указатель на элемент вектора становится недействительным, когда вы добавляете элементы в вектор. Посмотрите, что может сделать shared_ptr <>.
Показать ещё 3 комментария
Теги:
visual-c++

4 ответа

1
Лучший ответ

Проблема заключается в том, что вы сохраняете указатель на элементы dataTable но push_back делает недействительными эти указатели, если вектор изменен. Рассмотрим сделать dataTable и processTable вектор общих указателей, чтобы они не перемещаются.

vector<shared_ptr<data_entry>> dataTable;
vector<shared_ptr<process_entry>> processTable;

Я также изменил бы членов process_entry на общие указатели, пока вы на нем. С этими изменениями ваш раздел START теперь будет выглядеть примерно так:

            auto newEntry = make_shared<data_entry>();
            newEntry->text = "START";
            newEntry->time = atoi(line.substr(6, 6).c_str());
            dataTable.push_back(newEntry);

            auto newProcessEntry = make_shared<process_entry>();
            newProcessEntry->dataStart = dataTable.back();
            newProcessEntry->dataCurrent = dataTable.back();
            newProcessEntry->process = processAmount;
            processTable.push_back(newProcessEntry);

Другой вариант, который у вас есть, - использовать std::list который не будет копировать элементы вокруг, когда он вырастет.

2

Это присвоение должно возвращать тип ввода данных. Используйте ->dataCurrent чтобы получить указатель на data_entry, а затем разыменовать. Возможно, вы также захотите указать data_entry как const в зависимости от того, для чего он используется.

const data_entry test = *(processTable.at(i)->dataCurrent);
0

Вы заселена свои vectors с локальными переменными, которые создаются внутри в while цикла, и они не доступны из ограждающих if блок.

Поэтому, как только мы выходим из блока while, все локальные переменные уничтожаются, а vector указывает на группу bad_ptr s.

0

замещать

*processTable.at(i).dataCurrent;

от

*(processTable.at(i).dataCurrent);

Кроме того, у вас нет копии ctor и, таким образом, производится мелкая копия. Убедитесь, что это то, что вам нужно.

  • 0
    Этот код ничего не изменил.
  • 0
    Ты прав . моя вина .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню