Ben Sturmfels oznámil vydání MediaGoblinu 0.15.0. Přehled novinek v poznámkách k vydání. MediaGoblin (Wikipedie) je svobodná multimediální publikační platforma a decentralizovaná alternativa ke službám jako Flickr, YouTube, SoundCloud atd. Ukázka například na LibrePlanet.
TerminalPhone (png) je skript v Bashi pro push-to-talk hlasovou a textovou komunikaci přes Tor využívající .onion adresy.
Před dvěma lety zavedli operátoři ochranu proti podvrženým hovorům, kdy volající falšuje čísla anebo se vydává za někoho jiného. Nyní v roce 2026 blokují operátoři díky nasazeným technologiím v průměru 3 miliony pokusů o podvodný hovor měsíčně (tzn., že k propojení na zákazníka vůbec nedojde). Ochrana před tzv. spoofingem je pro zákazníky a zákaznice všech tří operátorů zdarma, ať už jde o mobilní čísla nebo pevné linky.
Společnost Meta (Facebook) předává React, React Native a související projekty jako JSX nadaci React Foundation patřící pod Linux Foundation. Zakládajícími členy React Foundation jsou Amazon, Callstack, Expo, Huawei, Meta, Microsoft, Software Mansion a Vercel.
Samsung na akci Galaxy Unpacked February 2026 (YouTube) představil své nové telefony Galaxy S26, S26+ a S26 Ultra a sluchátka Galaxy Buds4 a Buds4 Pro. Telefon Galaxy S26 Ultra má nový typ displeje (Privacy Display) chránící obsah na obrazovce před zvědavými pohledy (YouTube).
Byla vydána grafická knihovna Mesa 26.0.1 s podporou API OpenGL 4.6 a Vulkan 1.4. Je to první stabilní verze po 26.0.0, kde se novinky týkají mj. výkonu ray tracingu na GPU AMD a HoneyKrisp, implementace API Vulkan pro macOS.
Byla vydána nová verze 4.6 multiplatformního integrovaného vývojového prostředí (IDE) pro rychlý vývoj aplikaci (RAD) ve Free Pascalu Lazarus (Wikipedie). Využíván je Free Pascal Compiler (FPC) 3.2.2.
Byla vydána nová verze 3.23.0 FreeRDP, tj. svobodné implementace protokolu RDP (Remote Desktop Protocol). Opravuje 11 bezpečnostních chyb.
Španělský softwarový inženýr oznámil, že se mu podařilo na dálku ovládat sedm tisíc robotických vysavačů po celém světě. Upozornil tak na slabé kybernetické zabezpečení těchto technologií a jejich možné a snadné zneužití. Nesnažil se hacknout všechny robotické vysavače po světě, ale pouze propojil svůj nový DJI Romo vysavač se zařízením Playstation. Aplikace podle něj ihned začala komunikovat se všemi sedmi tisíci spotřebiči a on je
… více »Momo je fenka cavapoo, která svými náhodnými stisky kláves bezdrátové klávesnice vytváří jednoduché počítačové hry. Technicky to funguje tak, že Raspberry Pi s připojenou bluetooth klávesnicí posílá text do Claude Code, který pak v Godotu píše hry a sám je i testuje pomocí screenshotů a jednoduchých simulovaných vstupů. Za stisky kláves je Momo automaticky odměňována pamlsky. Klíčový je pro projekt prompt, který instruuje AI, aby i
… více »
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í).