kbz
kbz

Reputation: 1006

Why are elements not being added to my std::map (C++)

I'm parsing a file and want to add some data to a map so I can reference it later but I've been debugging and noticed that the elements aren't being added as I expect them to. If someone could point out the problem because I'm fairly new to C++ and usually work with maps in different languages.

std::map<const char *, const char*> MaterialParser::parseMaterial(const char * path) {
    std::map<const char *, const char *> materialMap;
    std::pair<const char *, const char *> pair;

    ifstream inFile;

    inFile.open(path);

    if (!inFile.good()) {
        std::cout << "Unable to open material file" << endl;
        return materialMap;
    }

    string materialName;

    while (!inFile.eof()) {

        string line;
        getline(inFile, line);

        if (line.substr(0, 6) == "newmtl") {
            materialName = line.substr(7);
        }
        else if (line.substr(0,3) == "map") {
            string dir = line.substr(7);

            //pair.first = materialName.c_str();
            //pair.second = dir.c_str();
            //materialMap.insert(pair);
            materialMap[materialName.c_str()] = dir.c_str();
        }


    }

    stringstream ss;
    ss << "MaterialData loaded. Size: " << materialMap.size() << endl;
    OutputDebugStringA(ss.str().c_str());

    inFile.close();

    return materialMap;
}

I've tried printing out whilst adding to the map, and right at the end and each time the size is only 1, when there are multiple elements in the file. I've printed out the data and it's reading correctly, just not adding to the map. Could someone tell me why please?

Output:

Adding material: Body_MiddlePath: assets\textures\plane\Body mid.dds  Size: 1
Adding material: Body_Parts_1  Path: assets\textures\plane\Body Par.dds  Size: 1
Adding material: Parts_11  Path: assets\textures\plane\parts 1.dds  Size: 1
Adding material: Body_rear  Path: assets\textures\plane\body rea.dds Size: 1
Adding material: body_front  Path: assets\textures\plane\body fro.dds Size: 1
Adding material: Wing_Detail  Path: assets\textures\plane\wing det.dds Size: 1
Adding material: Body_Tail  Path: assets\textures\plane\body tai.dds Size: 1
Adding material: Wing_Right  Path: assets\textures\plane\wing rig.dds  Size: 1
Adding material: Wing_Left  Path: assets\textures\plane\wing lef.dds  Size: 1
Adding material: interior_1  Path: assets\textures\plane\interior.dds  Size: 1
Adding material: body_parts_2  Path: assets\textures\plane\Body Par.dds  Size: 1
Adding material: Glass  Path: assets\textures\plane\glass 1.dds  Size: 1

MaterialData loaded. Size: 1

Upvotes: 0

Views: 103

Answers (1)

Messa
Messa

Reputation: 25191

Use std::map<std::string, std::string> instead of std::map<const char *, const char*>.

Problem is that the value you get from materialName.c_str() and store into the map as just const char * gets "undefined" after materialName is destroyed at the end of the function, so you are rewriting that const char * memory already stored in the map with new values.

The other problem is that const char * is just a number (a pointer to memory) and when inserted as a key to the map, it is compared just as a number, not as a string. Because the number (the pointer) is probably always the same (at the same position in the stack) the map gets filled with just one key.

Upvotes: 7

Related Questions