0

This is a highly simplified version of code in a bigger project. I think I am demonstrating the problem... I hope. Basically, I want a Task object that holds information about what needs to happen to a file (a file is just a string filepath right now). Later in the program I need to associate a Task with an item object so I can see what happened to that Task to update the item object by reading the Task. The problem is that my pointer to the Task gets screwed up.

The couts produce gibberish.

#include <iostream>
#include <map>
#include <vector>

using namespace std;

string getDir(string f)
{
    return "c:/";
}

class BatchFileChanger
{
public:

    struct Task
    {
        string origFile;
    };

    Task* addTask(string originalPath)
    {
        TASKS.push_back({});
        Task& t = TASKS.back();
        t.origFile = originalPath;
    
        taskMapNew[getDir(t.origFile)][t.origFile].push_back(&t);
    
        return &TASKS.back();
    }

    vector<Task> TASKS;

    //map of folder inside map of file of holding tasks
    //associates folder containing files which each file has one task
    //each file can only have one task
    //the reason for a map of vector of one task is to ensure a single task per file
    //so you can look up a file string and ensure there is only Task
    //ok i guess i could get rid of the vector...
    map<string, map<string, vector<Task*>>> taskMapNew;

};

int main()
{
    BatchFileChanger batch;
    
    batch.addTask("c:/a_file.wav");
    
    cout << batch.taskMapNew["c:/"]["c:/a_file.wav"][0]->origFile << "\n";
    cout << "\n";
    
    batch.addTask("c:/b_file.wav");
    
    cout << batch.taskMapNew["c:/"]["c:/a_file.wav"][0]->origFile << "\n";
    cout << batch.taskMapNew["c:/"]["c:/b_file.wav"][0]->origFile << "\n";
    cout << "\n";
    
    batch.addTask("c:/c_file.wav");
    
    cout << batch.taskMapNew["c:/"]["c:/a_file.wav"][0]->origFile << "\n";
    cout << batch.taskMapNew["c:/"]["c:/b_file.wav"][0]->origFile << "\n";
    cout << batch.taskMapNew["c:/"]["c:/c_file.wav"][0]->origFile << "\n";
    cout << "\n";

    return 0;
}

alternative int main

int main()
{
    BatchFileChanger batch;
    
    auto ptr1 = batch.addTask("c:/a_file.wav");
    
    cout << ptr1->origFile << "\n";
    cout << "\n";
    
    auto ptr2 = batch.addTask("c:/b_file.wav");
    
    cout << ptr1->origFile << "\n";
    cout << ptr2->origFile << "\n";
    cout << "\n";
    
    auto ptr3 = batch.addTask("c:/c_file.wav");
    
    cout << ptr1->origFile << "\n";
    cout << ptr2->origFile << "\n";
    cout << ptr3->origFile << "\n";
    cout << "\n";

    return 0;
}
Elan Hickler
  • 1,099
  • 1
  • 11
  • 28
  • 2
    `taskMapNew[getDir(t.origFile)][t.origFile].push_back(&t);` -- Ask yourself "what happens to those pointers that you are storing when the vector resizes?" – PaulMcKenzie Jul 28 '20 at 01:12
  • Perhaps you should use `vector` and dynamically allocate the tasks. Then you can return the task pointer, rather than the address of the vector element. – Barmar Jul 28 '20 at 01:17

0 Answers0