Я новичок в использовании основных фондов. Я хочу использовать словарь для хранения некоторой пары ключ-значение. Значение должно быть указателем на структуру. Этот указатель указывает на динамически распределяемый буфер.
CFMutableDictionaryRef init_hash_table() {
return CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
Это используется для создания словаря, а возвращаемое значение сохраняется как глобальная переменная.
CFNumberRef
create_hash_key(int sd) {
return CFNumberCreate(NULL, kCFNumberIntType, &sd);
}int
add_hash_entry(CFMutableDictionaryRef dict, int sd, void *pkt) {
CFNumberRef key = create_hash_key(sd);
CFDictionarySetValue(dict, key, pkt);
return 0;
}
Когда я выполняю этот код, я получаю segfault. Я вижу, что pkt имеет действительный адрес и ключ, кажется, создан. Кто-нибудь знает, как назначить указатель на значение part?
Программа получила сигнал EXC_BAD_ACCESS, Не удалось получить доступ к памяти.
Причина: KERN_INVALID_ADDRESS по адресу: 0x0000000000000011
0x00007fff8c9f339f в objc_msgSend_fixup ()
Есть идеи?
Проблема заключается в kCFTypeDictionaryValueCallBacks
аргумент. Из документации:
kCFTypeDictionaryValueCallBacks
предопределенныйCFDictionaryValueCallBacks
структура, содержащая набор
обратные вызовы, подходящие для использования, когда значения вCFDictionary
являются
всеCFType
объекты
Так что в вашем случае, CFRetain()
вызывается по указателю, когда значение добавляется к
толковый словарь. Это вызывает сбой, потому что указатель не указывает на CoreFoundation
объект.
Вы можете создать словарь с
CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
вместо этого, чтобы не было никакого «подсчета ссылок» для значения.
Кроме того, вы можете заключить указатель в CFDataRef
и положить это в
толковый словарь.
В обоих случаях вы несете ответственность за то, чтобы указатель действовал
когда значение извлекается из словаря позже.
Вот просто Пример того, как вы можете реализовать пересчет для ваших пользовательских объектов:
typedef struct {
int refcount;
int val;
} mystruct;
const void *myretain(CFAllocatorRef allocator, const void *value)
{
mystruct *p = (mystruct *)value;
p->refcount++;
return p;
}
void myrelease(CFAllocatorRef allocator, const void *value)
{
mystruct *p = (mystruct *)value;
if (p->refcount == 1)
free(p);
else
p->refcount--;
}
int main(int argc, const char * argv[])
{
mystruct *p = malloc(sizeof(*p));
p->refcount = 1;
p->val = 13;
CFDictionaryValueCallBacks vcb = { 0 , myretain, myrelease, NULL, NULL };
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &vcb);
int sd = 13;
CFNumberRef key = CFNumberCreate(NULL, kCFNumberIntType, &sd);
CFDictionarySetValue(dict, key, p);
// refcount == 2
myrelease(NULL, p);
// refcount == 1
mystruct *q = CFDictionaryGetValue(dict, key);
// refcount is still 1, "GetValue" does not increment the refcount
CFRelease(dict);
// object is deallocated
return 0;
}
Других решений пока нет …