내 응용 프로그램의 구성을 저장하기 위해 uthash.h을 사용하고 있습니다. 는 config 실행시 읽기 파일에서 오면, 해시 내의 키와 값이 모두 동적으로 char *
년대를 할당 :해시 테이블의 읽기가 잘못되었습니다.
typedef struct config_entry {
char *name;
char *value;
UT_hash_handle hh;
} CONFIG_ENTRY;
으로는 사용 설명서에 설명, 나는 키를 추가하는 내 자신의 기능을 구현 고유성을 보장하는 config-hash에 추가합니다. 여기에 있습니다 :
void cfg_put(char *name, char *value, FREE_FLAGS flags) {
CONFIG_ENTRY *entry;
//first, check if the key is already in the hash
HASH_FIND_STR(config_, name, entry);
if(entry == NULL) {
//key doesn't exist yet => create new one
entry = (CONFIG_ENTRY *)malloc(sizeof(CONFIG_ENTRY));
entry->name = name;
HASH_ADD_KEYPTR(hh, config_, entry->name, strlen(entry->name), entry);
} else {
//key exists => possibly free existing pointers before setting value
if((flags & FREE_NAME) == FREE_NAME) { //
free(entry->name); // these lines seem to be
} // problematic.
entry->name = name; //
if((flags & FREE_VALUE) == FREE_VALUE) {
free(entry->value);
}
}
//Finally, set the value
entry->value = value;
}
또한 구현을 점검하기위한 몇 가지 테스트 케이스를 작성했으며 제대로 실행되는 것 같습니다.
void test_config1(void) {
cfg_clear(FREE_ALL);
cfg_put(strdup("foo"), "bar", FREE_NONE);
CU_ASSERT_EQUAL(cfg_count(), 1);
CU_ASSERT_STRING_EQUAL(cfg_get("foo"), "bar");
cfg_dump();
cfg_put("foo", "baz", FREE_NAME);
CU_ASSERT_EQUAL(cfg_count(), 2);
CU_ASSERT_STRING_EQUAL(cfg_get("foo"), "baz");
cfg_clear(FREE_NONE);
cfg_dump();
}
cfg_get
:
==2561== Invalid read of size 1
==2561== at 0x4026097: bcmp (mc_replace_strmem.c:541)
==2561== by 0x804ADF5: cfg_get (in /home/gj/..../test/config_test)
==2561== by 0x804B2C7: test_config1 (in /home/..../test/config_test)
==2561== by 0x402E446: run_single_test (in /usr/local/lib/libcunit.so.1.0.1)
[...]
==2561== Address 0x4194210 is 0 bytes inside a block of size 4 free'd
==2561== at 0x4023B6A: free (vg_replace_malloc.c:366)
==2561== by 0x804A872: cfg_put (in /home/..../test/config_test)
==2561== by 0x804B27D: test_config1 (in /home/..../test/config_test)
==2561== by 0x402E446: run_single_test (in /usr/local/lib/libcunit.so.1.0.1)
[...]
다음은 테스트 케이스 및 완전성에 대한 cfg_get
의 구현이다 : 나는 memleaks를 확인하기 위해 Valgrind의를 사용하여 테스트를 실행하는 경우에는, 나는 항상 다음을 얻을
char *cfg_get(const char *name) {
CONFIG_ENTRY *entry = NULL;
HASH_FIND_STR(config_, name, entry);
if(entry) {
return entry->value;
} else {
return NULL;
}
}
어쨌든, 나는 name
-pointer에서 cfg_get
에 액세스하고있는 것 같습니다. 나는 그것을 cfg_put
에 겹쳐 썼다. 이 문제는 name
에만 발생하고 value
에는 발생하지 않습니다. 나는 그것을 알아 내기에는 너무 어리 석다.
프로그램이 멀티 스레드입니까? 여기서 문제가 될 수 있습니다. '휘발성'플래그가없는 변수는 레지스터로 이동할 수 있으며 원래 메모리 위치가 오래된 것일 수 있습니다. 또한'-O' 레벨이 버그에 영향을 미칩니 까? – Grapsus
@Grapsus 아니요, 관련된 스레드가 없습니다. 나는 또한 아무것도 바꾸지 않은 -O0로 빌드를했다. – DeX3