Re: Formátovaný tisk bylo Re: sprintf - co delam blbe?

Jan Waclawek konfera na efton.sk
Středa Duben 17 09:00:33 CEST 2024


> Jen mi není jasné, zda a kdy se pole buf na haldě uvolní.

Musel by to explicitne uvolnovat volajuci, potom, co sa cely string pouzije
(vytlaci, skopiruje - znova, neviem, co robi arduinovsky serial volaco).

Dynamicka alokacia pamate je peklo s viacerymi diablami, ktoreho pouzitie v
mcu musi byt mimoriadne dobre odovodnene a ako prva volba sa musi velmi
dobre zvazit aj napisanie vlastneho alokatora. 

Tento pripad podla mna ani zdaleka nepatri medzi odovodnene.

> V rámci testování bing chatu 

Moznost, ktoru zrejme nepouziva nikto, alebo nikto sa k nej verejne
nepriznava, a tym padom bing o nej ani nemoze vediet, je mat globalne pole
vyhradene priamo pre tuto ulohu (t.j. vytvaranie formatovacich retazcov).
Tiez je tam "problem s vlakny" (t.j. nereentrantnost toho riesenia),
dokonca to ani nemusia byt vlakna ale aj "ocakavana zivotnost" toho
retazca (t.j. problem, ze vysledny retazec musi byt cely
pouzity/vytlaceny/skopirovany, skor nez je dana funkcia znova zavolana).

Dalsia moznost je vytvaranie formatovacich retazcov in situ, t.j. priamo v
mieste pouzitia. Napr. ak vypisy idu cez seriak, tak priamo do nejakeho
buffra ktory tam pre ten seriak uz aj tak pravdepodobne existuje.

Obe tieto moznosti sa v skutocnosti prelinaju s relativne castym (co
dokazuje "google hlasovanie" v modernej verzii "bing doporucuje") riesenim
"volajuci musi zabezpecit miesto"; rozdiel je vo filozofii. Predstavme si,
ze formatovaciu funkciu pise osoba A a zvysok programu osoba B. V pripade
"volajuci musi zabezpecit miesto" osoba A napise funkciu bez ohladu na
zvysok programu a predpise osobe B vsetky poziadavky, ktore B musi splnit
aby sa dana funkcia mohla pouzit. V pripade, ze funkciu pise B a to potom,
co uz boli urobene dolezite rozhodnutia o tom, ako program ma vyzerat, ta
funkcia sa prisposobi filozofii celeho programu, napr. ak ma vediet pisat
in-situ do kruhoveho buffera, no tak je napisana s ohladom na tuto
poziadavku.

Ako vravim, v mcu neexistuje "najlepsie" riesenie, vsetko je kontextovo
zavisle. Pre Arduino/C++ je ta implicitna instanciacia cez navratovu
hodnotu (ak to skutocne funguje dobre a nie su s tym spojene nejake
chytaky) celkom dobre riesenie, lebo v Arduine sa aj tak nehra na
efektivnost.

wek




----- Original Message ---------------

Takže takto? Je to opravdu kratší.

char * Fultoa(uint32_t val,uint8_t length,uint8_t decimal) {
   uint8_t ld1 = length - decimal - 1;
   uint8_t ld2 = ld1 - 1;
   char * buf = (char *)malloc(11);
   uint32_t k=100;
   for (uint8_t i = 3;i < length; i++) k*=10;
   ultoa(val+k, buf, 10);
   for (uint8_t i = 0; i < ld2; i++) {
     if (buf[i + 1] == '0')
       buf[i] = ' ';
     else
       buf[i] = buf[i + 1];
   }
   buf[ld2] = buf[ld1];
   buf[ld1] = '.';
   return buf;
}

Jen mi není jasné, zda a kdy se pole buf na haldě uvolní.

Martin Záruba

Dne 17.4.2024 v 8:08 Ladislav Vaiz napsal(a):
> On 17.04.2024 7:44, Martin Záruba wrote:
>> String Fultoa(uint32_t val, uint8_t length, uint8_t decimal) {
>>   uint8_t ld1 = length - decimal - 1;
>>   uint8_t ld2 = ld1 - 1;
>>   char buf[11];
>>   uint32_t k=100;
>>   for (uint8_t i = 3;i < length; i++) k*=10;
>>   ultoa(val+k, buf, 10);
>>   for (uint8_t i = 0; i < ld2; i++) {
>>     if (buf[i + 1] == '0')
>>       buf[i] = ' ';
>>     else
>>       buf[i] = buf[i + 1];
>>   }
>>   buf[ld2] = buf[ld1];
>>   buf[ld1] = '.';
>>   return buf;
>> }
>
>
> V rámci testování bing chatu jsem mu zkusil zadat optimalizaci pro 
> AVR. Navrhl místo Stringu vracet static char buf[11] definovaný ve 
> funkci. U toho zmínil problém s vlákny (což na AVR nebude tak horké), 
> k tomu navrhl řešení pomocí pole definovaného volajícím a předávaného 
> funkci.
>
> To poslední mi připadne nejlepší. Vyhnete se režiji Stringu a buffer 
> bude alokován, jen když ho volající bude potřebovat.
>
> L.



Další informace o konferenci Hw-list