I made a small linked map for my C project. And I'm using this map for cache my checks, I'm putting current file path to map. If the same file path request again, it has to get value from the cache map.
struct StrBoolNode {
const WCHAR* key;
BOOL* value;
struct StrBoolNode* next;
};
struct StrBoolTable {
struct StrBoolNode* first;
};
BOOL* strBoolTable_get(struct StrBoolTable* table, const WCHAR* key) {
wprintf(L"TEST strBoolTable_get %s \n", key);
struct StrBoolNode* node = table->first;
while (node != NULL) {
wprintf(L"strBoolTable_get WHILE %s \n", node->key); <<< prints here broken
if (wcscmp(key, node->key) == 0) return node->value;
node = node->next;
}
return NULL;
}
void strBoolTable_push(struct StrBoolTable* table, const WCHAR* key, BOOL value) {
wprintf(L"TEST strBoolTable_push 1 %s \n", key); <<< prints here normal
struct StrBoolNode* tmp = (StrBoolNode*)malloc(sizeof(struct StrBoolNode));
tmp->key = cloneKey;
tmp->value = (BOOL*)malloc(sizeof(BOOL));
*(tmp->value) = value;
tmp->next = NULL;
wprintf(L"TEST strBoolTable_push 2 %s \n", tmp->key); <<< prints here normal
if (table->first == NULL) {
table->first = tmp;
wprintf(L"TEST strBoolTable_push 3 %s \n", table->first->key); <<< prints here normal
return;
}
struct StrBoolNode* node = table->first;
while (node->next != NULL) {
node = node->next;
}
node->next = tmp;
wprintf(L"TEST strBoolTable_push 4 %s \n", node->next->key); <<< prints here normal
}
struct StrBoolTable cacheMap = { NULL };
WCHAR szFileName[MAX_PATH];
HMODULE hModule = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)retAddr,
&hModule);
GetModuleFileNameW(hModule, szFileName, 2048);
BOOL* cacheVal = strBoolTable_get(&cacheMap, szFileName);
if (cacheVal != NULL) return *cacheVal;
wprintf(L"Check => %s \n", szFileName); <<<< szFileName prints normal
strBoolTable_push(&cacheMap, szFileName, TRUE);
return TRUE;
There is no problem when pushing object to this map, but when I iterate and print the key in object, it returns unicode chars. Like this "Ï,♥". Why does my object's key change to this later?
I marked where printed wrong print with <<<< in the code.
CodePudding user response:
What is cloneKey
that I see referenced in strBoolTable_push
. It's note declared anywhere. How does that code compile?
My psychic powers suggest you are pushing a local array variable:
WCHAR szFileName[MAX_PATH];
Into your collection. But as soon as the function declaring szFileName
returns, all bets are off (undefined behavior). The memory space is easily reclaimed and overwritten by anything that happens after the function returns. Your key
is getting corrupted in the linked list when this happens.
Make sure you duplicate the string key before persisting it into your collection:
void strBoolTable_push(struct StrBoolTable* table, const WCHAR* key, BOOL value) {
wprintf(L"TEST strBoolTable_push 1 %s \n", key); <<< prints here normal
struct StrBoolNode* tmp = (StrBoolNode*)malloc(sizeof(struct StrBoolNode));
// wcsdup is equivalent to saying: tmp->key = malloc((wcslen(key) 1)*sizeof(WCHAR))); wcscpy(tmp->key, key);
tmp->key = _wcsdup(key);
Likewise, when you take a node out of list, make sure you free
both the key
and value
members of each node.