• std::map not accessing?
    9 replies, posted
When I try to access any map data after setting it, it accesses the last item set. [code]0000:AAAA00018000000180004A51EA505A51C99E0001800000018000000180005555 0001:AAAA00018000000180003993C252325F8A527193800000018000000180005555 0002:AAAA00018000000180003BA5C124311989247125800000018000000180005555 0003:AAAA00018000000180007BA5C1247919C1247925800000018000000180005555 0004:AAAA000180000001800079BFC2487A49C2487989800000018000000180005555 0005:AAAA00018000000180007A4DC2527B53C2D67A4F800000018000000180005555 0006:AAAA000180000001800031A5CA287A31CA2849A5800000018000000180005555 0007:AAAA000180000001800073D1CA1073D1CA1073DF800000018000000180005555 0008:AAAA000180000001800078E1C50078C1C42079C1800000018000000180005555 0009:AAAA000180000001800045F1C4407C41C4404441800000018000000180005555 000A:AAAA000180000001800041F1C10041F1C1007D01800000018000000180005555[/code] [cpp] std::map<int, char*> lines; FILE *file = fopen("unifont.hex", "r"); for(int i=0;i<=10;i++)//while(feof(file) == false) { char buffer[128]; fscanf(file, "%s", buffer); char code[5]; strncpy(code, buffer, 4); code[4] = '\0'; char data[124]; strncpy(data, buffer + 5, 123); data[123] = '\0'; int id = strtol(code, 0, 16); lines[id] = data; printf("%i-%s\n", id, lines[id]); } printf("\n%i=%s\n", 5, lines[5]);[/cpp] Output, note the array then the how accessing it shows the last item set. [code]0-AAAA00018000000180004A51EA505A51C99E0001800000018000000180005555 1-AAAA00018000000180003993C252325F8A527193800000018000000180005555 2-AAAA00018000000180003BA5C124311989247125800000018000000180005555 3-AAAA00018000000180007BA5C1247919C1247925800000018000000180005555 4-AAAA000180000001800079BFC2487A49C2487989800000018000000180005555 5-AAAA00018000000180007A4DC2527B53C2D67A4F800000018000000180005555 6-AAAA000180000001800031A5CA287A31CA2849A5800000018000000180005555 7-AAAA000180000001800073D1CA1073D1CA1073DF800000018000000180005555 8-AAAA000180000001800078E1C50078C1C42079C1800000018000000180005555 9-AAAA000180000001800045F1C4407C41C4404441800000018000000180005555 10-AAAA000180000001800041F1C10041F1C1007D01800000018000000180005555 5=AAAA000180000001800041F1C10041F1C1007D01800000018000000180005555[/code]
I believe the reason is because the string is stored in the local array "data", however there is only one array which gets overwritten and hence why it only returns the last one. Additionally the array goes out of scope after the for loop, but you are still accessing it so that is a memory leak in a way. (Not specifically that name, I'm not sure what you would call it - You know what I mean though.) You need to allocate memory for each line, I believe strcpy will do that for you. Even better would be to store a map of stl strings instead.
And the "C++ version" of FILE is std::fstream.
[QUOTE=yngndrw;21402212]Not specifically that name, I'm not sure what you would call it[/QUOTE] Undefined behavior.
It's probably to do with the fact you're storing char pointers (alternatively you can use std::string).
Ugh, silly me. I thought the compiler would tell me that I was trying to put char in to a char* map. Thanks for your posts guys, it helped.
[QUOTE=CPPNOOB;21412648]Ugh, silly me. I thought the compiler would tell me that I was trying to put char in to a char* map. Thanks for your posts guys, it helped.[/QUOTE] I don't think you get it. You are putting char pointers (char*) into the map, and the compiler would indeed complain if you tried to input plain chars. The problem is that you are overwriting that memory on every iteration of your loop. You are also invoking undefined behaviour by using that memory (in your printf statement) after exiting the loop (where the memory is allocated).
Yeah, I think I get it. I just thought that I'd have to dereference data in order to put in the map. I think I also get that since I printed data that was out of the scope, it could of invoked undefined behaviour.
[QUOTE=CPPNOOB;21412938]it could of invoked undefined behaviour.[/QUOTE] Not "could have", "did". Dereferencing pointers to variables that have gone out of scope is [i]always[/i] UB. It's just that "seems to work correctly" is one of the many possible outcomes of UB. You should make your map hold std::string rather than char*. The general reason is that std::string is the preferred way to work with strings in C++, and the additional specific reason in this situation is that std::string's copy constructor actually copies the string contents, so as you add entries to the map in your loop, you get actual different strings rather than a bunch of pointers to the same string.
Well, I'm using strings now. Thanks for all the help, guys.
Sorry, you need to Log In to post a reply to this thread.