Zdravím, potřeboval bych vysvětlit jednu podivnost. Na Linuxu používám libdispatch v kódu v C, vytvořím si čítač (int counter) a ten pak používám v blocích, které dávám do fronty. Na hlavním vlákně si chci občas přečíst hodnotu, mám tam ukazatel na counter, ale program při čtení *counter spadne. Evidentně to nějak souvisí s těmi bloky, když je fronta prázdná, kód běží. Má s touto knihovnou někdo zkušenosti?
Asi by tochtelo nekam hodit ten kod, nebo aspon ukazku. Co presne je mysleno tim lokalni promenna? Pokud je tim mysleno opravdu lokalni promenna tak na tu nedava smysl delat ukazatel a ten pouzivat nekde mimo, jelikoz to kam ten pointer ukazuje uz nemusi existovat
Struktura kódu je takováto:
int main() {
__block int c = 0;
printf("%p\n", &c);
dispatch_async(...);
printf("%p\n", &c);
...
}
Ty dva printfy vypisují různé adresy. Potřebuju předat jiné asynchonní knihovně ukazatel na ten čítač jako parametr (void*), proto to řeším, ale nevím, jak to udělat bezpečně, aby ten ukazatel zůstal platný. Funkce main nakonec končí ve smyčce událostí, takže proměnné na zásobníku zůstávají platné.
Když padá kód bez zjevné chyby, hodíme to na překladač. Někde v dispatch_async se volá Block_copy (kvůli zařazení do fronty), což obnáší kopii kontextu bloku ze zásobníku na haldu. Neměnitelné lokální proměnné se klonují, měnitelné se přealokují na haldě. Celé to řeší překladač a runtime, v knihovnách nic není. Taky pozor na to, že po posledním Block_release ta proměnná zmizí (automaticky se dealokuje). Ono to je celé trochu magie a __block je lepší nepoužívat.