Přední technologické společnosti (Adobe, Cadence, Capital One, Cisco, Cloudera, Cloudflare, Cognition, CrowdStrike, Databricks, Dell Technologies, DoorDash, Elastic, HPE, Hugging Face, IBM, LangChain, Linux Foundation, Microsoft, NAVER, NetApp, Nous Research, NVIDIA, OpenClaw, Palantir, Palo Alto Networks, Red Hat, Reflection AI, Salesforce, SAP, ServiceNow, Siemens, SK Telecom, Snowflake, SpacexAI, Synopsys, Thinking
… více »Krabix.cz je online 3D konfigurátor krabiček pro 3D tisk s exportem do STL. Běží přímo v prohlížeči. Nic se neposílá na server.
Nadace Open Home Foundation spustila veřejnou preview verzi komunitní databáze zařízení pro Home Assistant. Má fungovat jako „Wikipedie pro chytrá zařízení".
Na stránce nového panelu Firefoxu přibudou nové widgety. Například denně aktualizována interaktivní křížovka.
PGSimCity (GitHub) je webová 3D vizualizace vnitřního fungování databázového systému PostgreSQL v podobě města. Vytvořena pomocí umělé inteligence.
UBports, nadace a komunita kolem Ubuntu pro telefony a tablety Ubuntu Touch, vydala Ubuntu Touch 24.04-2.0 a 24.04-1.4. Nová verze 24.04-2.0 již počítá s výřezy pro fotoaparát (notch) a zaoblenými rohy displeje. Webový prohlížeče Morph přešel z Chromia 87 na Chromium 134. Do shellu Lomiri byl přidán editor snímků obrazovky.
Byly zveřejněny informace o kritické zranitelnosti CVE-2026-64600 pojmenované RefluXFS (technické detaily) v XFS. Je tam již od verze Linuxu 4.11, tj. rok 2017. Jedná se o lokální eskalaci práv. Neprivilegovaný uživatel může editovat libovolný soubor, například klidně zrušit rootovské heslo v /etc/passwd. Videoukázka na Vimeo. V upstreamu je zranitelnost opravena.
OpenAI / ChatGPT má dnes výpadky (OpenAI Status, DownDetector).
Poskytovatel hostingu svobodných/open-source projektů Codeberg po hlasování na valné hromadě vydal stanovisko k využívání LLM. Kvůli vytěžování infrastruktury a rostoucím cenám hardwaru, ale také hrozbám pro spolupráci v komunitě se k LLM staví kriticky. Nebude poskytovat hosting projektů vytvářených LLM agenty.
Jack Dorsey představil (𝕏) open source týmovou komunikační platformu Buzz (GitHub) s cílem snížit závislost na Slacku a GitHubu.
Tiskni
Sdílej:
#ifndef SORTING_H #define SORTING_H char **alloclines(int n); char **realloclines(char** memold, int *nold); int cmp(char *s1, char *s2); int readline(char *l); void freelines(char **l, int n); void print(char **l, int n); #endifSprav, nech načítava ne do prázdneho riadku, ale dokiaľ je vstup. Vstup ukončíš v konzole CTRL + D. ...
if(fgets(...) == NULL)
{
// vstup bol ukončený
}
A funkciu main dávaj nakoniec v súbore (alebo najdôležitejšiu funkciu, ak tam nie je main v zdrojovom kóde). Taký nejaký profesionálnejší štandard.
A ďalšia poznámka. Neplytvaj pamäťou. Tj. alokuj pamäť na riadok, až keď budeš mať riadok načítaný. Vtedy vieš jeho veľkosť, a miesto MAXLINE alokuješ reálnu veľkosť.
A použi štruktúru (dátový typ), popíš ňou riadky a s ňou pracuj. A aj tú daj na spracovanie funkciám ako parameter. To potom bude krása.
A keď chceš profesionálnejšie, tak aj testuj stupy pre funkcie. Chyba je NULL, a co ak všade pošlem napr. pre char **realloclines(char** memold, int *nold) ako memold NULL alebo *NULL;
.h soubor pouze pro main.c opravdu moc nemá moc smysl. .h soubor má smysl, pokud ho bude někdo includovat, nejlépe více souborů než jen main.c
Tvoj program skoro robí ako príkazy # cat | sortIf you hold a UNIX shell up against your ear. Can you hear the C? :-)
Tvoj program skoro robí ako príkazy # cat | sort A ďalšia poznámka. Neplytvaj pamäťou. Tj. alokuj pamäť na riadok, až keď budeš mať riadok načítaný. Vtedy vieš jeho veľkosť, a miesto MAXLINE alokuješ reálnu veľkosť.Jednoduché řešení je mít samostatný buffer pro vstup a v okamžiku, kdy je řádek načtený, tak ho vykopírovat na čílové místo něčím na způsob
strdup(), takže se použije jen tolik paměti, co je třeba. Onen vstupní buffer může být ve většině případů dokonce staticky alokovaný, případně dynamicky alokovaný na určitou předem nastavenou velikost, protože pokud nepotřebujeme neomezeně dlouhé řádky, je jednodušší řešení nesmyslně dlouhé řádky zahazovat (k čemu je např. konfugurační soubor, z jehož čtení nám půjdou oči šejderm a při jehož editaci se uscrollujeme k smrti
) .
No a pokud je třeba dynamická alokace, tak nemá smysl zvyšovat velikosti po jednotkách byte, minimální granularita většiny implementací hald je většinou kolem šestnácti byte a pokud se paměť opravdu přidává, tak je to minimálně o velikosti jedné stránky (4KB na x86 a běžných ARMech, dá se zjistit dynamicky přes getpagesize() nebo sysconf()). Když už, tak zvětšovat právě o velikost stránky nebo něco strovnatelného.
Mimo toho, že se ušetří čas, kderý by se zbytečně trávil managementem haldy (bez toho, že by zavolal sbrk()), to má vliv i na nižší fragmentaci haldy, obzvlášť pro pesimální případy, kde délka řádku monotóně roste s jeho pozicí (takže nelze znovu použít uvolněné "díry" v haldě).
PS: Když se toto alokuje opravdu, ale opravdu hodně (IIRC, limit je 128MB u GNU libc), tak malloc() a spol. začnou požívat místo haldy přímé mapování anonymní paměti pčes mmap() (tedy, v unixech, jask se to dělá ve Windows, nemám potuchy). Osobně si myslím, že pak je lepší se na paměťový management přes malloc() a spol. vykvajznout a buď použít nějaký lepší alokátor, nebo si to dělat ručně právě přes malloc(), což má navíc výhodu v tom, že můžeme mnohem přesněji ovlivnit, jak se s pamětí nakládá (přes madvise())nebo kdy se paměť uvolní (nutné, když jednu chvíli potřebujeme spoustu paměti a v té náskledujcí jí musíme zase uvolnit pro někoho jiného).
IIRC, limit je 128MB u GNU libcMoje mallopt(3) říká, že ten limit je 128 KiB.
tak malloc() a spol. začnou požívat místo haldy přímé mapování anonymní paměti pčes mmap()Python (resp. CPython) dělá něco takového taky. Debugování memory leaků je pak výborný :-/
>>> import kerberos
>>> kerberos.authGSSClientInit("HTTP@krbhost.example.com")
(1, <PyCObject object at 0x7f56004e65d0>)
>>>
Ano, muze za to kerberos modul napsany v C, ale hadam ze debugovani python C extensions mel prave kralyk na mysli.
Měmory leak v Pythonu? Wtf?Python-C interop. Céčková strana naalokuje nějaké pythonní objekty a neuvolní je. Tyhle objekty můžou bejt naalokovaný přes malloc, ale někdy taky přes mmap (zcela bez volání mallocu). Nástroje jako valgrind a podobně tohle nedohledají. Nakonec jsem to řešil trasováním mmap syscallu a koukal na backtraces, abych zjistil, odkud se to alokuje. Možná existuje chytřejší způsob.
Jasně. Jak výše vyplynulo, leakuje nějakej c bazmek, ale může za to Python.Tenhle čistě pythonní kód u mě sežere ~1GB RAM:
#!/usr/bin/env python2
import sys
class Foo(object):
def __init__(self, other=None):
self.other = other
def __del__(self):
pass
if __name__ == "__main__":
for i in range(1000000):
foo = Foo()
bar = Foo(foo)
baz = Foo(bar)
foo.other = baz
sys.stdin.readline()
(V Pythonu 3 mi to nejde reprodukovat, proto then python2)
Jinak ale leaky jdou vytvořit i bez triků s __del__, viz třeba tenhle kód:
#!/usr/bin/env python3
import sys
foobar = []
def avg_line_length(file):
avg = len(file.readline())
if avg == 0:
return 0
else:
avg -= 1
n = 1
for line in file:
n += 1
avg = avg + (len(line) - 1 - avg) / n
foobar.append(line)
return avg
if __name__ == "__main__":
print(avg_line_length(sys.stdin))
sys.stdin.readline()
Tady je sice hodně zřejmý, kde a proč to leakuje, ale jakmile budeš mít nějakou větší codebase ve který bude podobný problém zašmodrchaný a rozetřený přes X modulů, už nebude tak snadný to dohledat.
Tož tak.
Já tomu python3 kódu moc nerozumím, ale za ten leak považuješ ten foobar?Jj. Kvůli němu má ten program lineární paměťovou složitost místo konstantní.
foobar v tom prográmku výše není k ničemu potřeba, ale GC to nepozná. Být to v nějakém jazyce s nějakým chytrým kompilátorem, mohl bys dostat warning, něco jako "Value assigned to foobar is never used" nebo podobně...
A ano, to, jestli program nějaký resource potřebuje, může být věc názoru. Např. v některých C/C++/apod. programech jsou objekty, který se jednou naalokujou a záměrně nikdy neuvolní. Valgrind to může označit za leak, ale přitom programátor to za leak nepovažuje.
Být to v nějakém jazyce s nějakým chytrým kompilátorem, mohl bys dostat warning, něco jako "Value assigned to foobar is never used" nebo podobně...Nevím, jak u pole, ale u obecného objektu dost těžko – máš totiž nějakou instanci a na ní voláš nějakou metodu (
append) a jestli tu instanci pak někam přiřadíš nebo s ní uděláš něco jiného je jedno – ta užitečnost mohla spočívat v tom, že jsi volal tu metodu a instance na základě toho něco dělala.
leakuje nějakej c bazmek, ale může za to Python.Za leak může C bazmek, to je bez debat. Za to, že ten leak šel blbě dohledat nicméně může CPython, protože se snaží bejt chytrej a používat vlastní alokační fígle s
mmap(). Jak moc jsou tyhle fígle užitečný, to nevim, možná jsou, ale mám svoje pochybnosti...
int pro účel velikosti něčeho v paměti. Velikost toho typu může být nedostatečná, nebo naopak příliš velká. Používej typ size_t. Funkce jako malloc, calloc, realloc, všechny mají parametr typu size_t. Funkce qsort taky očekává parametry typu size_t. Používáním intu se můžeš dopustit závažných chyb, např. přetečení a následné předání špatné velikosti daným funkcí, kvůli konverzím.
2) Pokud funkce realloc selže, původní buffer není uvolněn. Máš tam možný memory leak ... sice hned voláš exit(), ale může tě to naučit špatným zvyklostem, třeba až takovou kontrolu někdy dáš do nějaké vlastní knihovny, co ukončovat program nebude.
3) Komparátor funkce qsort má typ int (*)(const void *, const void*). Tvůj má úplně jinou signaturu. To přetypování je hnus, nejsem si jistý, ale asi se dokonce bude jednat i o UB, teoreticky by ty funkce nemusely být volatelné stejným způsobem. A obzvláště, když v tom komparátoru stejně přetypováváš, tak můžeš nechat signaturu správně.
4) Dynamická alokace je většinou od toho, abys nemusel mít nějaký fixně veliký buffer, což stejně pro jednotlivé řádky máš. Jednotlivé řádky bych alokoval až poté, co ho přečteš.
5) Asi je zbytečné mít extra funkci pro realokaci, funkci realloc můžeš předat NULL jako první parametr a bude se chovat jako malloc. Stačí inicializovat proměnnou předem na NULL a nemusíš pak mít 2 funkce, co dělají to samé.
6) Ukazatele (kromě ukazatelů na funkce) jsou implicitně přetypovatelné na void*, netřeba přetypovávat, pokud voláš funkci free(). void* ukazatele jsou implicitně přetypovatelné na ukazatele na jiné (platí pouze v C, v C++ to neplatní).