String - C jezik

Moderator: tilz0R

String - C jezik

OdgovorNapisal/-a arksi » 22 Sep 2015, 15:34

Malo se igram s stringi v začetniškem stadiju ;-) in prosim za kašen komentar, če jaz tole okoli stringov razumem prav.

Najprej definiram string spremenljivko. Vsak string naj bi se končal z znakom 0x00 (null).
Torej moram definirati string spremenljivko, ki ima najmanj sedem znakov in, da je spremenljivka pravilno definirana moram na koncu dodati še znak 0x00.?

Npr:
moj_string[7] //definiramo velikost string spremenljivke
moj_string="zdravo" //v spremenljivko dodamo posamezme znake

Če prav razumem lahko napišemo tudi tako:
moj_string[0]="z"
moj_string[1]="d"
moj_string[2]="r"
moj_string[3]="a"
moj_string[4]="v"
moj_string[5]="o"
moj_string[6]="0"

Sedaj me pa zanima, če si jaz tole razlagam pravilno? Kajse zgodi, če na koncu stringa ne dodam znaka null (0x00)?

Nekje sem opazil, da uporabljajo tudi sintakso na koncu stringa - "\n", "/r" ali "/0". Kaj od tega je sedaj pravilno?
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a PeterC » 22 Sep 2015, 16:42

Na koncu stringa je vedno 0.

\n je znak za novo vrstico. Obstajajo še:

Koda: Izberi vse
    \t (tab)
    \v (vertical tab)
    \f (new page)
    \b (backspace)
    \r (carriage return)
    \n (newline)

Za /r sploh ne vem, če kaj pomeni...
Time is like a fuse, short and burning fast --Metallica
PeterC
 
Prispevkov: 87
Pridružen: 26 Jan 2015, 19:39
Zahvalil se je: 12 krat
Prejel zahvalo: 6 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 3

Re: String - C jezik

OdgovorNapisal/-a S53DZ » 22 Sep 2015, 18:12

\0 je oznaka za konec stringa (sestavni del),
\r je v C-ju kontrolni znak za pomik na začetek vrstice brez pomika v novo vrsto.
Uporabniški avatar
S53DZ
 
Prispevkov: 1407
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 274 krat
Prejel zahvalo: 468 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 49

Re: String - C jezik

OdgovorNapisal/-a IgorK » 22 Sep 2015, 19:48

A ne bi bilo bolj enostavno, da si poiščeš eno knjigo o C, na netu je tega kot smetja, in najprej prebereš vsaj osnove, potem pa začneš s konkretnimi vprašanji? Tudi primerov je ogromno in tam črpaj znanje, potem pa kar pogumno vprašaj, če kaj ne bo jasno.
IgorK
 
Prispevkov: 813
Pridružen: 20 Feb 2015, 00:08
Kraj: Rače
Zahvalil se je: 5 krat
Prejel zahvalo: 174 krat
Uporabnika povabil: s56rir
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a gregoral » 22 Sep 2015, 20:19

Za prehod v novo vrstico programi na:
- unix, linux, ..., običajno uporabljajo '\n'
- Windows* običajno uporabljajo '\r\n'

Kontrolni znaki izvirajo iz mehanskih teleprinterjev, kjer je \r pomenil premik glave na začetek vrstice, \n pa za eno vrstico naprej v smeri tiskanja.
Tako se je dejansko dalo natisniti eno vrstico čez drugo.
Če recimo malo ugibam: "cszCSZ\rˇˇˇˇˇˇ\r\n" bi recimo lahko pomenil izpis 蚞ȊŽ.

No verjetno je šlo samo za kake posebne primere.
Recimo da menjava fonta traja celo večnost. Potem najprej izpišemo vse znake v normalni pisavi, zamenjamo pisavo na krepko, skočimo nazaj na začetek, izpišemo okrepljen tekst, potem ponovimo enako še za italic, subscript, superscript, ...
Recimo znak bell (zvonček) je bil (če nisem česa zamešal) dejansko namenjen zvonenju, da je operater vedel da se je tiskanje končalo. Tiskalniki so bili verjetno preglasni da bi bili v isti sobi.

Ok nazaj na C.
Znak \0 (null) se uporablja za null-terminated stringe. Večina v C vgrajenih funkcij je bila napisana tako, da je pričakovala da bo zadnji veljaven znak \0.
Zato funkcije kot so strcmp, strcpy, strlen, strcat, ... v zanki obdelujejo znake dokler ne pridejo do \0.

Torej če znak \0 prepišemo, kaj se zgodi?
- ob samem prepisu znaka se ne zgodi nič, saj je tista lokacija v pomnilniku sigurno veljavna (prej je bil tam \0)
- dokler takega stringa ne podamo kot parameter v katero od zgoraj omenjenih funkcij bo vse ok
- če pa ga pošljemo kot parameter, bo recimo funkcija strlen seštevala dolžino dokler ne bo nekje v pomnilniku "naletela" na znak \0 (to je kar resen bug, žal tudi precej pogost)
- če bo pred tem kaka neveljavna lokacija bo OS program ustavil in dobimo sporočilo podobno temu:
"Program ta in ta ... referenced ... unallocated memory ... and will be shut down."

Skratka null-terminated stringi so le ena izmed oblik zapisovanja tekstov.
Če uporabljamo kako drugo knjižnico, potem ni nujno da so stringi zaključeni z \0, lahko imamo nekje drugje shranjeno dolžino.

Tako da izjava: "Na koncu stringa je vedno \0" ne drži (vsaj ne vedno).
Recimo med izvajanjem strcpy že ne drži!

Primer:
strcpy(Mem, "0123456789");
Pred izvajanjem zgornjega stavka je recimo na lokaciji Mem tole:
Mem: vfnsduklhdfsd

Vsaka vrstica tule spodaj je prikaz lokacije Mem po "času":
Mem: vfnsduklhdfsd
Mem: 0fnsduklhdfsd
Mem: 01nsduklhdfsd
Mem: 012sduklhdfsd
Mem: 0123duklhdfsd
Mem: 01234uklhdfsd
Mem: 012345klhdfsd
Mem: 0123456lhdfsd
Mem: 01234567hdfsd
Mem: 012345678dfsd
Mem: 0123456789fsd
Mem: 0123456789\0sd

Torej kot vidimo se znak '\0' zapiše šele ko je operacija končana.
Če bi med tem ta string poskusili prebrati iz druge niti (multithreaded/večnitno izvajanje programa),
bi seveda prišlo do nepredvidenega delovanja programa (beri napake v programu).

Nekatere funkcije uporabljajo tudi koncept \0\0.
Tako lahko z enim kazalcem pošljemo recimo seznam (funkciji ki to pričakuje seveda):
Mem: prva\0druga\0tretja\0četrta\0peta\0rikverc\0\0
Če bi taki funkciji kot parameter poslali "prva\0" bi bilo to seveda narobe, poslati bi morali "prva\0\0".

Podobno je za unicode (double-byte, multi-byte) tekste.
Tam so recimo znaki angleške abecede (~ASCII) zapisani takole:
Mem: \0H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!\0\0

Torej (velja za double-byte) vsak znak je zapisan z dvemi byti. Za angleške znake velja da je prvi znak \0 potem pa ascii vrednost. Za naše šumnike to seveda ne velja, oba byta bi bila za "naše" znake različna od '\0'.

No toliko na kratko o tekstih v C in C++.

Lp, gregor
gregoral
 
Prispevkov: 184
Pridružen: 19 Jan 2015, 11:12
Kraj: Ljubljana
Zahvalil se je: 9 krat
Prejel zahvalo: 85 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 10

Re: String - C jezik

OdgovorNapisal/-a arksi » 23 Sep 2015, 06:55

Naj se zahvalim še pisno ;-). Sem bil skoraj prepričan, da se ne bo nikomur ljubilo razlagat in, da bodo spet samo nasveti v stilu Google, poglej si to in ono, naštudiraj to in to...... Pa sem prijetno presenečen, da je še kdo na forumu, ki se mu ljubi oddati kakšen koristen post (da se vse ne vrti okoli beguncev).
Seveda, naj bo jasno, da ne sprašujem nekaj na pamet in sem nekaj osnov C-ja že nekajkrat prebral. V bistvu sem prebral že n-krat, pa kot vidim, bo treba še n-krat..... ampak, enostavno nekatere stvari mi niso jasne. Hehe, imam, žal, pač dolgo "lajtngo" ;-). Vem, da so tistim, ki obvladajo C vprašanja "otročja", ampak, če se komu ne ljubi odgovarjati, naj pač spregleda to temo.

No, da ne bom preveč off., še eno vprašanje.

Zanima me kako pravilno izbrišem string?
Je prav tako, ali kako drugače?

moj_string="zdravo" --> izbrišem tako --> moj_string=""

torej so na vseh lokacijah potem 0x00 (null)??
moj_string[0]="0"
moj_string[1]="0"
moj_string[2]="0"
moj_string[3]="0"
moj_string[4]="0"
moj_string[5]="0"
moj_string[6]="0"
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a S53DZ » 23 Sep 2015, 07:15

Za "brisanje" niza je dovolj:

moj_string = "";

ali pa

moj_string[0] = 0;

Ostalih znakov niza se s tem ne dotakneš. Kar je logično, a ne?
Uporabniški avatar
S53DZ
 
Prispevkov: 1407
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 274 krat
Prejel zahvalo: 468 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 49

Re: String - C jezik

OdgovorNapisal/-a eboc » 23 Sep 2015, 08:54

morda še to kljub temu, da je string zbrisan je spomin (7 bytov) še vedno allociran .... kamor lahko vpišeš string dolg do 6 zankov.
eboc
 
Prispevkov: 379
Pridružen: 19 Jan 2015, 11:12
Zahvalil se je: 168 krat
Prejel zahvalo: 66 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a peterp » 23 Sep 2015, 09:03

gregoral je napisal/-a:Nekatere funkcije uporabljajo tudi koncept \0\0.
Tako lahko z enim kazalcem pošljemo recimo seznam (funkciji ki to pričakuje seveda):
Mem: prva\0druga\0tretja\0četrta\0peta\0rikverc\0\0
Katere pa so te funkcije?
peterp
 
Prispevkov: 1179
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor okolica
Zahvalil se je: 392 krat
Prejel zahvalo: 243 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 247

Re: String - C jezik

OdgovorNapisal/-a arksi » 23 Sep 2015, 09:11

S53DZ je napisal/-a:....moj_string[0] = 0;
Ostalih znakov niza se s tem ne dotakneš. Kar je logično, a ne?


Če prav razumem je stanje string spremenljivke sedaj takšno:
moj_string[0]="0"
moj_string[1]="d"
moj_string[2]="r"
moj_string[3]="a"
moj_string[4]="v"
moj_string[5]="o"
moj_string[6]="0"

Če v naslednjem koraku dam v string spremenljivko npr. samo dve črki npr. moj_string="OK", bo stanje tako:
moj_string[0]="O"
moj_string[1]="K"
moj_string[2]="r"
moj_string[3]="a"
moj_string[4]="v"
moj_string[5]="o"
moj_string[6]="0"

S53DZ je napisal/-a:Za "brisanje" niza je dovolj:
moj_string = "";


To mi pa ni najbolj jasno kaj se zgodi s spremenljivko moj_string. Je znak 0x00 potem samo na prvem mestu, ali se definira na vseh lokacijah od [0] do [6]?
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a eboc » 23 Sep 2015, 09:13

samo na 1. mestu. S
eboc
 
Prispevkov: 379
Pridružen: 19 Jan 2015, 11:12
Zahvalil se je: 168 krat
Prejel zahvalo: 66 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a arksi » 23 Sep 2015, 09:31

eboc je napisal/-a:samo na 1. mestu. S


Aha, sedaj razumem ;-).

eboc je napisal/-a:morda še to kljub temu, da je string zbrisan je spomin (7 bytov) še vedno allociran .... kamor lahko vpišeš string dolg do 6 zankov.


Kaj si hitel točno s tem stavkom povedati?

LP
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a eboc » 23 Sep 2015, 09:46

Povedat sem hotel, da brisanje stringa še ne pomeni sprostitve spomina.

V bistvu se za string alocira / rezervira določen del spomina - nekaj baytov.
Šele potem lahko na to lokacijo vpišeš string.
Se pravi:
char string[7]; /* alocira 7 bytov in teh 7 baytov ima lahko čudno vrednost - neinicalizirano */

string[0]='a';
strig[1]='b';
string[2]=0;

Nastaviš string na ab.

Potrebno je tudi razlikovati med "a" in 'a'. Prvo je string torej a + 0 drugo pa je sam znak a oz, koda znaka a (=97).

Je pa tako, da imaš različen "dialekte" jezikov in so stvari lahko razlikujejo. .....

Sicer bi na tvojem mestu vzel v roke kakšno C knjigo recimo K&R in se potem malo igral recimo na PC-u ....
eboc
 
Prispevkov: 379
Pridružen: 19 Jan 2015, 11:12
Zahvalil se je: 168 krat
Prejel zahvalo: 66 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a VolkD » 23 Sep 2015, 10:24

eboc je napisal/-a:Povedat sem hotel, da brisanje stringa še ne pomeni sprostitve spomina.


eboc je napisal/-a:Je pa tako, da imaš različen "dialekte" jezikov in so stvari lahko razlikujejo. .....
Sicer bi na tvojem mestu vzel v roke kakšno C knjigo recimo K&R in se potem malo igral recimo na PC-u ....


Pri PC-ju se mi nikoli ni zdelo pomembno vedeti kdaj in kako se spomin sprosti. To sem vedno prepustil sistemu. S stališča mene kot uporabnika je bilo spomina vedno dovolj. Povsem nekaj drugega pa so mikrokontrolerji, kjer spomina vedno manjka.
In tu se "dialekti" različnih C-jev še kako poznajo.
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a arksi » 23 Sep 2015, 10:28

eboc je napisal/-a:..........
Potrebno je tudi razlikovati med "a" in 'a'. Prvo je string torej a + 0 drugo pa je sam znak a oz, koda znaka a (=97).


No, na tole si mi pa že kar sam odgovoril. Ravno to sem mislil še vprašati. Kaj je pravzaprav razlika med "a" in 'a'. Vem, da si podal že razlago, ampak mi ni najbolj jasno. Ok, prvo je string. Drugo je koda znaka (=97) --> to je dec v ASCII zapisu. Kako se pa to potem ta znak uporablja?
Pa kje dobiš na tipkovnici take narekovaje 'a'. Jaz jih ne najdem.

eboc je napisal/-a:..........Je pa tako, da imaš različen "dialekte" jezikov in so stvari lahko razlikujejo. .....
Sicer bi na tvojem mestu vzel v roke kakšno C knjigo recimo K&R in se potem malo igral recimo na PC-u ....


Saj imam nekaj literature. Sem jo bral, jo berem in jo bom še bral ;-). Kot berem naj bi bila knjiga K&R prezahtevna za začetnika.
Ampak, a ni boljše, da se tukaj napiše nekaj osnov, pa bodo prišle prav gotovo komu prav, kot pa , da trolamo ne tehnične teme ala "rešimo svet" in podobne.?
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a arksi » 23 Sep 2015, 10:36

VolkD je napisal/-a: .......Povsem nekaj drugega pa so mikrokontrolerji, kjer spomina vedno manjka.
In tu se "dialekti" različnih C-jev še kako poznajo.


Tole kar sprašujem, bi uporabljal izključno za programiranje AVR mikrokontrolerjev.
V bistvu sem že naredil eno majhno aplikacijo (s pomočjo kode z neta) z Arduino-tom in GSM modemom, da, ko pošljem SMS mi le-ta vklopi bojler.
To sem sprogramiral z Flowcode, ki je grafični program in programiraš z posameznimi bloki. V bloke pa potem poljubno lahko vstavljaš še kodo v C ali ASM.

Ja pa pri tem slabost, da ne veš kaj se v teh blokih v zakulisju procesorja dogaja. Zato sedaj malo raziskujem in poizkušam klasičen C.

LP
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a Kroko » 23 Sep 2015, 11:09

Tudi na PC-ju je pomembno, da spomin sproščaš drugače hitro ostaneš brez. VolkD je verjetno uporabljal okolja in jezike, ki so to naredili namesto njega.
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a eboc » 23 Sep 2015, 12:09

arksi je napisal/-a:
No, na tole si mi pa že kar sam odgovoril. Ravno to sem mislil še vprašati. Kaj je pravzaprav razlika med "a" in 'a'. Vem, da si podal že razlago, ampak mi ni najbolj jasno. Ok, prvo je string. Drugo je koda znaka (=97) --> to je dec v ASCII zapisu. Kako se pa to potem ta znak uporablja?
Pa kje dobiš na tipkovnici take narekovaje 'a'. Jaz jih ne najdem.


string[0]='a';
je isto kot:
string[0]=97;

torej na lokacijo v spominu se vpise 97 in se potem to interpretira kot črka a v tem primeru.

char string[]="a";
Pa rezervira v spominu 2 bayta, na prvo lokacijo se vpise 97 (koda a) na drugo pa 0 (zaključek stringa)
/*
char string[7];
string="a";
Ta stvar pa moce dela samo v kaksnem dialekt ;-)
*/
eboc je napisal/-a:..........Je pa tako, da imaš različen "dialekte" jezikov in so stvari lahko razlikujejo. .....
Sicer bi na tvojem mestu vzel v roke kakšno C knjigo recimo K&R in se potem malo igral recimo na PC-u ....


Saj imam nekaj literature. Sem jo bral, jo berem in jo bom še bral ;-). Kot berem naj bi bila knjiga K&R prezahtevna za začetnika.
Ampak, a ni boljše, da se tukaj napiše nekaj osnov, pa bodo prišle prav gotovo komu prav, kot pa , da trolamo ne tehnične teme ala "rešimo svet" in podobne.?[/quote]

Glede K&R: zavis, jaz bi "zagrizel". Mogoče v 1. ne razumeš vseh detajlov, a se potem pozneje lahko vračaš.
Verjetno obstajajo še kakšne druge knjige / literatura ....
Najboljše pa je malo eksperimentirati in se igrati in se učiti na napakah kot recimo:
char st[]="abc";
printf("%c\n", st[0]);
printf("%c\n", st[1]);
printf("%c\n", st[2]);
printf("%c\n", st[3])

st[2]=97;
printf("%c\n", st[2]);

... ..
Mi je všeč, da se poglabljaš in hočeš razumet stvari, to ti pride zelo prav ko nastopijo problemi.
eboc
 
Prispevkov: 379
Pridružen: 19 Jan 2015, 11:12
Zahvalil se je: 168 krat
Prejel zahvalo: 66 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a arksi » 23 Sep 2015, 13:08

@eboc :_bow ....bom tole sedaj še malo poizkusil v praktičnem svetu mikrokontrolerjev (verjetno Mega328p - Arduino UNO).

eboc je napisal/-a:... ..
Mi je všeč, da se poglabljaš in hočeš razumet stvari, to ti pride zelo prav ko nastopijo problemi.


Ja ravno tole me je hecalo, ker nisem vedel "detailov". Pošiljal sem string v GSM, ga pobrisal, vendar, ko sem potem poslal krajši string so se zraven "prilepili" še ostali znaki, ki so ostali od prejšnjega brisanja. Hjauuuu, so se kravžali možgani, ko človek ne ve detailov.

Je pa večina vodičev okrog jezika C napisana bolj nasplošno in še nisem zasledil npr. podrobne razlage okoli "a" in 'a' ter podobnih reči...

p.s. Pa kje dobiš na tipkovnici take narekovaje 'a'. Jaz jih ne najdem.
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a mirkatmir » 23 Sep 2015, 13:31

pri meni so pod vprašajem.
lp, Miran (Miro S51SK)
Uporabniški avatar
mirkatmir
 
Prispevkov: 1506
Pridružen: 14 Jan 2015, 22:05
Kraj: Ribnica - JN75IR
Zahvalil se je: 229 krat
Prejel zahvalo: 380 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 60

Re: String - C jezik

OdgovorNapisal/-a gregoral » 23 Sep 2015, 14:36

VolkD je napisal/-a:... Pri PC-ju se mi nikoli ni zdelo pomembno vedeti kdaj in kako se spomin sprosti. To sem vedno prepustil sistemu. ...


Huuh, če si programiral v C-ju potem je to ... hmm, kako bi se izrazil ... nevem ... mogoče velika šlamparija.

Primera funkcij ki jemljejo double-null ( sem moral pogooglat, ker že nekaj let nisem rabil ):
SHFileOperation
ChangeServiceConfig

Omenjeno je bilo spoščanje pomnilnika.
Tole je malo bolj obširna tema.
Najprej je treba vedeti kako je bil pomnilnik rezerviran, potem pa lahko govorimo še o tem kako se sprosti.

Rezervacija pomnilnika:
----------------------------------------
a) alokacija na stacku
b) alokacija na heapu
c) alokacija globalne spremenljivke

a) alokacija na stacku
----------------------------------------
lokalna spremenljivka v funkciji
int Nekafunkcija()
{
char[10] buffer;

strcpy(buffer, "123456");

return 0;
}

tule je treba vedeti da:
- velikost stacka je omejena ( odvisno ali gre za windows, linux, 32bitni proces, 64bitni proces, embedded platformo, ...)
char[65536] buffer; // to je recimo na PC računalniku lahko čisto ok, na mikrokontrolerju pa verjetno ni
- če imamo rekurzivni klic funkcije je treba dovro premisliti kako bo delovalo da ne bo zmanjkalo naslovnega prostora
- vnaprej moramo predvideti kakšna bo največja dolžina teksta ki ga bomo "tlačili" v ta buffer
- upoštevati je treba še prostor za '\0'
- ko se bo funkcija končala se bo sprostil tudi spomin rezerviran za tako spremenljivko
- paziti je treba da ne zapišemo več znakov kot je velikost bufferja, sicer se prepiše vsebina naslednje spremenljivke

int BufferOverwriteDemo()
{
char[10] buffer;
char[10] buffer2;

strcpy(buffer, "0123456798012345");

// tule bo (odvisno od tega kako so stvari zložene v pomnilniku)
// del našega teksta pristal v buffer2!
// program se zelo verjetno ne bo sesul, ker nismo prepisali ničesar drugega

return 0;
}


b) alokacija na heapu
----------------------------------------
int HeapAllocDemo(int bufSize)
{
char *buffer = new char[bufSize];

strcpy(buffer, "0123456798012345");

// buge:
// - nismo preverili če je bufSize večji od dolžine teksta ki ga želimo zapisati
// - tukaj bi morali naslov alociranega pomnilnika sprostiti ali pa spraviti v nek seznam za kasneje

return 0;
}

- alokacija na heapu je bolj "fleksibilna"
- pomnilnik lahko ostane rezerviran tudi po izhodu iz funkcije
- ni treba med pisanjem programa vedeti kakšna bo dolžina podatkov
- če konstantno alociramo in sproščamo pomnilnik se (lahko) pojavi efekt fragmentacije naslovnega prostora
- temu se delno lahko izognemo če recimo vedno alociramo velikosti 2^n bytov ( 2, 4, 8, 16, 32, 64, ... )
recimo za "abcd" alociramo 8 bytov: strlen("abcd")+1 = 4+1 = 5 => nextpowerof2(5) = 8

int HeapAllocDemoFixed(int bufSize)
{
char *buffer = new char[bufSize];
if(!buffer) retrn -1;

if (bufSize <= strlen("0123456798012345")) return -2;
strcpy(buffer, "0123456798012345");

// do something useful with string

delete buffer;

return 0;
}

c) alokacija globalne spremenljivke
----------------------------------------
char[10] globalBuffer;
int GlobalVarDemo()
{
strcpy(globalBuffer, "0123456798012345");

// buge:
// - nismo preverili če je gobalBuffer večji od dolžine teksta ki ga želimo zapisati

return 0;
}

- tukaj je spremenljivka deklarirana kot statiče array in za sprostitev pomnilnika bo poskrbel prevajalnik




Posebno zabavne so funkcije za pretvorbo v tekst (sprintf):
sprintf(buffer, "%s %i", "0123456798012345", 1);

- pri teh funkcijah je probel to ker ni enostavno izračunati koliko podatkov (teksta) bodo zapisale.
- zato modernejše različice ( recimo snprintf ) vsebujejo dolžino bufferja kot parameter
- tako lahko funkcija sama preneha pistai če pride do konca bufferja in ne prepiše vsebine v pomnilniku ki se nahaja za bufferjem

Torej osnovni napotek:
- če alociramo tako: int[] xyz; ... char[128] username; ... potem bo prevajalnik sam poskrbel da se bo spomin sprostil
- če alociramo tako: int *xyz = new int[3]; ... char *username = new char[128]; byte *buff = malloc(1024); ... potem mormao spomin sprostiti sami (delete, free, ...)

Lp,
Gregor
gregoral
 
Prispevkov: 184
Pridružen: 19 Jan 2015, 11:12
Kraj: Ljubljana
Zahvalil se je: 9 krat
Prejel zahvalo: 85 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 10

Re: String - C jezik

OdgovorNapisal/-a s54mtb » 23 Sep 2015, 15:15

Za alokacijo lahko skrbi tudk rtos s svojimi funkcijami, ki so ponavadi bolj robustne od malloc in free, sploh pri bolj resnih rtosih.
Always going the extra mile.
https://www.buymeacoffee.com/s54mtb
Uporabniški avatar
s54mtb
 
Prispevkov: 14710
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 2183 krat
Prejel zahvalo: 6096 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a VolkD » 23 Sep 2015, 15:19

gregoral je napisal/-a:
VolkD je napisal/-a:... Pri PC-ju se mi nikoli ni zdelo pomembno vedeti kdaj in kako se spomin sprosti. To sem vedno prepustil sistemu. ...


Huuh, če si programiral v C-ju potem je to ... hmm, kako bi se izrazil ... nevem ... mogoče velika šlamparija.
Sem kar vedel da bo prišlo do takega posta.
No mojo izjavo treba jemati s točke gledanja nekoga, ki programira mikrokontroler.

Tu je stvar malo drugačna, kot prvo moraš za vse alokacije poskrbeti sam, za sprostitev teh pa tudi. Ni nobenega OS zadaj, ki skrbi za te stvari. Ko nek program ki je pisan za PC starta, se točno ve, da bo tudi končal. Ob koncu bo za vse programerjeve packarije poskrbel OS. Pri mikrokontrolerju tega ni. Alokacojo, ki je nisi sprostil ob recimo koncu inicializacije bo program nosil s sabo za večno. In cel čas bomo trpeli pomanjkanje RAM-a.
PC programer se praktično nikoli ne sreča s tem, da je potrebno RAM šparati. Programer, ki programira za mikrokontroler, pa se mora tega ves čas zavedati.
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a Proteus » 23 Sep 2015, 15:39

VolkD je napisal/-a:Programer, ki programira za mikrokontroler, pa se mora tega ves čas zavedati.

No neke prav velike panike pa tudi pri uC ni.
(1) Najprej moraš pri sebi razčistiti koliko globalnih spremenljivk pravzaprav potrebuješ. Te ti memorijo zasedajo konstantno.
(2) Nadalje steku moraš pustiti dovolj prostora da diha.
(3) Nekaj prostora potrebuješ še za lokalne spremenljivke.

2 in 3 malce težje optimiraš, lahko pa optimiraš 1.
Pomembno torej je, da se ti globalne spremenljivke ne razpasejo preko vseh koordinat. Če potrebuješ 8 bitno vrednost, potem ni potrebna 32 bitna spremenljivka za shranjevanje te vrednosti itd...
Uporabniški avatar
Proteus
 
Prispevkov: 3363
Pridružen: 18 Jan 2015, 01:31
Kraj: Planet Zemlja
Zahvalil se je: 361 krat
Prejel zahvalo: 737 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 136

Re: String - C jezik

OdgovorNapisal/-a gregoral » 23 Sep 2015, 15:50

VolkD je napisal/-a:No mojo izjavo treba jemati s točke gledanja nekoga, ki programira mikrokontroler. ...

Sami izgovori. :)

VolkD je napisal/-a:PC programer se praktično nikoli ne sreča s tem, da je potrebno RAM šparati.

Popravek: Kvazi PC "programer" se s tem ne sreča!
PC programer pa se s tem sreča, in tudi programira tako kot je treba!

Če govorimo o "Hello world" aplikaciji ali kakšnem programčku tipa "calc" potem mogoče ni kritično, sicer pa je.

Programirajte tako kot je treba!
Če se zavedate da bi nekaj morali narediti potem to tudi naredite!

Če se le da ne pisat "špageti" kode, razen mogoče za "osebno uporabo" med učenjem/razvojem nekega algoritma.

Jaz imam po več mesecev odprte programe in tisti ki so vredni naziva program brez težav delujejo tudi več mesecev, kljub temu da vsak dan kaj naredim v njih.

LP, Gregor
gregoral
 
Prispevkov: 184
Pridružen: 19 Jan 2015, 11:12
Kraj: Ljubljana
Zahvalil se je: 9 krat
Prejel zahvalo: 85 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 10

Re: String - C jezik

OdgovorNapisal/-a Kroko » 23 Sep 2015, 16:00

Gre se predvsem za to, da vsak "new" potrebuje svoj "delete", vsak "malloc" svoj "free",...
Če tega ne delaš...

Sicer pa tudi pri C# ni vse samo od sebe. Objektom, ki implementirajo "IDisposable" interface je potrebno klicati "Dispose" ali pa uporabiti "using". Razni streami potrebujejo "Close". Pa še bi se lahko našlo.
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a peterp » 23 Sep 2015, 17:15

gregoral je napisal/-a:Primera funkcij ki jemljejo double-null ( sem moral pogooglat, ker že nekaj let nisem rabil ):
SHFileOperation
ChangeServiceConfig
Zgleda, da je to specifika Windows funkcij. Za Linux kaj takega ne poznam (razen lastne implementacije).

gregoral je napisal/-a:Rezervacija pomnilnika:
----------------------------------------
a) alokacija na stacku

Zanmiva je še alokacija s alloca(), ki rezervira pomnilnik na skladu (podobno kot malloc) in se sprosti avtomatsko, ko zapustimo funkcijo.
Ne vem pa koliko je to smiselno na mikrokrmilnikih.
peterp
 
Prispevkov: 1179
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor okolica
Zahvalil se je: 392 krat
Prejel zahvalo: 243 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 247

Re: String - C jezik

OdgovorNapisal/-a VolkD » 23 Sep 2015, 17:25

gregoral je napisal/-a:
VolkD je napisal/-a:No mojo izjavo treba jemati s točke gledanja nekoga, ki programira mikrokontroler. ...

Sami izgovori. :)

VolkD je napisal/-a:PC programer se praktično nikoli ne sreča s tem, da je potrebno RAM šparati.

Popravek: Kvazi PC "programer" se s tem ne sreča!
PC programer pa se s tem sreča, in tudi programira tako kot je treba!

Če govorimo o "Hello world" aplikaciji ali kakšnem programčku tipa "calc" potem mogoče ni kritično, sicer pa je.

Čakaj, čakaj, ... Niso izgovori! Ti bi torej bi rad povedal, da je vseeno ali imaš na razpolago vsega skupaj 1k RAM-a ali pa nekaj GB ?
Ni vseeno! Način programiranja se zelo hitro spremeni. Še posebej, če imaš program, ki se ukvarja s hitrimi prenosi podatkov. Buffer, ki si ga v nekaj k RAM-a lahko privoščiš je treba čim prej izprazniti.
Pri PC-ju tega ni!
In preden nekomu rečeš kvazi programer, se pozanimaj kako je s tem. 30 let sem s programiranjem uspešno preživljal sebe in družino. In to še v času, ko nisi mogel na internet po primere kako se kaj naredi. 10 let sem že upokojen zaradi možganske kapi. Moji programi pa pri kar nekaj strankah še vedno delajo, brez da bi potrebovali posege.
Pa saj tega nebi niti vedel, pa so me prosili, da jih prenesem na novejše računalnike.

gregoral je napisal/-a:Programirajte tako kot je treba!
Če se zavedate da bi nekaj morali narediti potem to tudi naredite!
Se strinjam.

gregoral je napisal/-a:Če se le da ne pisat "špageti" kode, razen mogoče za "osebno uporabo" med učenjem/razvojem nekega algoritma.
Jaz imam po več mesecev odprte programe in tisti ki so vredni naziva program brez težav delujejo tudi več mesecev, kljub temu da vsak dan kaj naredim v njih.
Se bolje počutiš, ko si druge ozmerjal, da pišejo spageti kodo ?
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a blasny » 23 Sep 2015, 17:34

VolkD je napisal/-a:Tu je stvar malo drugačna, kot prvo moraš za vse alokacije poskrbeti sam, za sprostitev teh pa tudi. Ni nobenega OS zadaj, ki skrbi za te stvari. Ko nek program ki je pisan za PC starta, se točno ve, da bo tudi končal. Ob koncu bo za vse programerjeve packarije poskrbel OS.

Ne drži. Serverske aplikacije, ki laufajo 24/7, mesece in leta ne smejo imeti nobenih memory leakov. Noben OS ne bo čistil packarij.
In isto velja tudi za navadne programe. A naj uporabniki 3x na dan restartajo program, ker je skuril ves pomnilnik, ki je na voljo. Ker se programerju ni dalo pucat za sabo? Samo pri amaterskih programih se lahko tako razmišlja.
blasny
 
Prispevkov: 849
Pridružen: 18 Jan 2015, 16:48
Kraj: Tepanjce
Zahvalil se je: 545 krat
Prejel zahvalo: 333 krat
Uporabnika povabil: VolkD
Število neizkoriščenih povabil: 36

Re: String - C jezik

OdgovorNapisal/-a VolkD » 23 Sep 2015, 17:41

@blasny: na mikrontrolerju je tvoj program hkrati tudi OS. Pri PC-ju ni tako. To je bistvena razlika.
Načeloma tvoj program na PC-ju konča in kontrolo prepusti OS-ju. Pri mikrokontrolerju se to ne zgodi nikoli.

Pri programih, ki tečejo pod nekim OS-om je treba vedeti, da že prevajalniki poskrbijo, da ti za kup stvari pravzaprav kličeš funkcije, ki so stvar OS-ja. In te funkcije za sabo čistijo in pucajo, vse kar je potrebno. Zato ti tega ni potrebno početi.
Pri programu, ki teče na mikrokontroleru moraš vse storiti sam (razen, če imaš kak RTOS).
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a s54mtb » 23 Sep 2015, 17:44

Eno so aplikacije, ki jih pozenes, nekaj naredis in zapres. Poleg streznikov so tudi aplikacije, ki tecejo zelo dolgo in vmes delajo cuda.

Ravno to se je dogajalo s programom za koncni test senzorjev. Zaradi slampaste implementacije sql knjiznice za delphi in kasneje bcb je prihajalo do memory leaka. To pa je zadnje kar si zelis na kosu softvera, ki tece 24/7 v proizvodnji s 3 izmenami. Po popravkih in workaroundih je imela merilna aplikacija uptime enak trajanju med rednimi remonti in to na win98 :)
Always going the extra mile.
https://www.buymeacoffee.com/s54mtb
Uporabniški avatar
s54mtb
 
Prispevkov: 14710
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 2183 krat
Prejel zahvalo: 6096 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a Proteus » 23 Sep 2015, 17:45

Pri uC se tudi ni potrebno pretirano matrati, da povoziš kakšen podatek.
Ta nevarnost je še posebej prisotna, ko kaj vpisuješ v pomnilnik preko pointerjev.
Takšne napake so še posebej trdovratne za debagirat.
Uporabniški avatar
Proteus
 
Prispevkov: 3363
Pridružen: 18 Jan 2015, 01:31
Kraj: Planet Zemlja
Zahvalil se je: 361 krat
Prejel zahvalo: 737 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 136

Re: String - C jezik

OdgovorNapisal/-a gregoral » 23 Sep 2015, 19:38

@VolkD: Nič letelo nate osebno, niti na nikogar drugega poimensko.

Sicer se oddaljujemo od teme ampak:
Tudi če bo OS "pobrisal" pomnilnik za programom in tudi če bo zaprl datoteke, to še ne pomeni da potem po mili vilji alociramo pomnilnik in potem tega nikjer ne sprostimo, ker bo itak OS poskrbel za to.

Ta logika je mimo in pripelje do slabo delujočih programov.
Pogojno mogoče recimo lahko naredimo eno globalno strukturo ki je živa ves čas delovanja programa in je potem ne pobrišemo sami, da bi pa to počeli vsevprek povsod kjer nam zmanjka volje in idej kako zadevo implementirati, ..., no to je pa šlamparija.

In kdor kar tako brez res zelo tehtnega razloga ne pobriše tistega kar je alociral, si žal ( vsaj pri po mojem mnenju ) ne zasluži naziva programer.

Če govorimo o mikrokrmilniku in točno določenih par bufferjih potem seveda deklariramo jih globalno in ves čas bodo zasedali isto lokacijo in to je to.

Zavedati se je treba da imajo tudi OS napake zaradi katerih morda ne bodo za vami počistili vse svinjarije.
Ok pri pomnilniku mogoče ja, sicer pa ni nujno ( koncept je splošen in velja za vse primere ko nekaj rezerviramo, zaklenemo, ... ).

Ok če se vrnem na temo stringov.

Double-null ternminated strings.
@peterp: "Zgleda, da je to specifika Windows funkcij."
Ne drži koncept je splošen.

Obstajata dve varianti tega koncepta:
a) double-null terminated
b) empty string terminated

Razlika se pojavi ko taka struktura ne vsebuje nobene besede:
a) double-null terminated => "\0\0"
b) empty string terminated => "\0"

Recimo da želimo nekje imeti seznam 100.000 prepovedanih besed, za ... no za karkoli.
Kako lahko to shranimo?
1) lahko za vsako besedo posebaj alociramo košček pomnilnika (moramo imeti tudi seznam teh koščkov)
2) lahko za vse besede alociramo v en velik kos pomnilnika

Varianta 1 je potratna in v določenih primerih počasna.
Pri varianti 2 pa moramo potem imeti način kako vse besede zapisati da jih potem znamo prebrati.
Najbolj enostavna je struktura, kjer besede zapisujemo eno za drugo, za vsako zapišemo \0, konec pa označuje prazen tekst (z dolžino 0).
To pomeni da bo zadnji besedi sledil prazen niz: "....\0beseda\0\0".
Če pa nimamo nobene besede, pa bi to zapisali takole: "\0".
Pozor če ni nobene besede potem pri taki formulaciji končamo po prvem in edinem '\0'!
Ker je to precej pogosta napaka zato običajno pri sestavljanju praznega niza za vsak slučaj lahko brez kake škode vseeno zapišemo "\0\0".


Double null terminated string ima kar nekaj zanimivih (pozitivnih) lastnosti:
- če poznamo skupno dolžino lahko "strukturo"/seznam kopiramo ali shranimo s klicem ene funkcije
- prenos take strukture med dvema procesoma je relativno enostaven
- relativno enostavno se lahko shrani v kako key-value "bazo" podatkov
- "struktura" ne potrebuje serializacije, ker je že serializirana

Če to primerjamo z rešitvijo kjer za vsako besedo svoj košček pomnilnika:
- kako tako strukturo posredovati kot parameter
- kako jo zapisati v datoteko
- kako jo prenesti preko serijskega porta
- kako ...

No vsekakor ima tako prednosti kakor tudi slabosti.
Recimo izbris ene besede iz sredine take strukture je ... no recimo da je "kompliciran".
Taka struktura tudi ne more vsebovati praznega stringa, ker je to oznaka za konec/terminacijo.

LP, Gregor
gregoral
 
Prispevkov: 184
Pridružen: 19 Jan 2015, 11:12
Kraj: Ljubljana
Zahvalil se je: 9 krat
Prejel zahvalo: 85 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 10

Re: String - C jezik

OdgovorNapisal/-a peterp » 23 Sep 2015, 20:19

gregoral je napisal/-a:Double-null ternminated strings.
@peterp: "Zgleda, da je to specifika Windows funkcij."
Ne drži koncept je splošen.
Seveda je splošen koncept, saj sem to tudi napisal. Ampak obe omenjeni funkciji sta Windows related. Sem malce brskal za kakšnimi standardnimi funkcijami na Linux sistemu pa jih nisem našel.
peterp
 
Prispevkov: 1179
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor okolica
Zahvalil se je: 392 krat
Prejel zahvalo: 243 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 247

Re: String - C jezik

OdgovorNapisal/-a sundancer » 23 Sep 2015, 22:07

VolkD je napisal/-a:@blasny: na mikrontrolerju je tvoj program hkrati tudi OS. Pri PC-ju ni tako. To je bistvena razlika.
Načeloma tvoj program na PC-ju konča in kontrolo prepusti OS-ju. Pri mikrokontrolerju se to ne zgodi nikoli.

Pri programih, ki tečejo pod nekim OS-om je treba vedeti, da že prevajalniki poskrbijo, da ti za kup stvari pravzaprav kličeš funkcije, ki so stvar OS-ja. In te funkcije za sabo čistijo in pucajo, vse kar je potrebno. Zato ti tega ni potrebno početi.
Pri programu, ki teče na mikrokontroleru moraš vse storiti sam (razen, če imaš kak RTOS).


V priponki je screenshot porabe pomnilnika iz neke linux skatle na kateri tece strezniska aplikacija 24/7.
Nekdo ni pucal bufferjev za seboj. In ker OS nic ne puca je rezultat tak kot lahko vidis na screenshotu.
Ker obcasno restartam strezniski proces in za trenutek unmountam swap nastane na grafu strmina saj se kolicina pomnilnika sprosti. Ja, takrat pa OS spuca. Prej pa ne. Zato podpiram vse tiste, ki pravijo, da moramo programirati tako, da za seboj pucamo RAM. Pa naj bodo to mikrokontrolerski kilobajti ali multicore procesorji z gigabajti RAM-a.
Nimate dovoljenj za ogled prilog tega prispevka.
Uporabniški avatar
sundancer
 
Prispevkov: 979
Pridružen: 16 Jan 2015, 23:36
Kraj: Ljubljana
Zahvalil se je: 438 krat
Prejel zahvalo: 534 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 63

Re: String - C jezik

OdgovorNapisal/-a SolarCharger » 23 Sep 2015, 22:32

VolkD je napisal/-a:
eboc je napisal/-a:Povedat sem hotel, da brisanje stringa še ne pomeni sprostitve spomina.


eboc je napisal/-a:Je pa tako, da imaš različen "dialekte" jezikov in so stvari lahko razlikujejo. .....
Sicer bi na tvojem mestu vzel v roke kakšno C knjigo recimo K&R in se potem malo igral recimo na PC-u ....


Pri PC-ju se mi nikoli ni zdelo pomembno vedeti kdaj in kako se spomin sprosti. To sem vedno prepustil sistemu. S stališča mene kot uporabnika je bilo spomina vedno dovolj. Povsem nekaj drugega pa so mikrokontrolerji, kjer spomina vedno manjka.
In tu se "dialekti" različnih C-jev še kako poznajo.

Ne znate brati. Ste funkcionalno nepismeni.

VolkD je povedal eno, vi pa zdaj že cel dan trobite drugo. Nobena razlaga ne pomaga. Mislite, da mora vedno vse viseti na pointerjih in rezervacijah spomina.
Razen tega je malo takih, ki bi vedelo v kaj se prevede koda iz Cja.
Izgleda, da sem samo jaz tole razumel prav:

Ko pišem v C za PC potem si lahko privoščim imeti celo vse spremenljivke globalne. Imam dovolj RAM-a na razpolago. Ko pišem za AVR-je potem je to drugače. Če neko spremenljivko potrebuješ samo za nekaj šteti se jo splača definirat v proceduri, ki bo to štela. Ko je procedure konec, ni spremenljivke več. To mesto lahko zasede neka druga iz neke druge procedure.
Še boljši izkoristek rama lahko dosežem z uporabo asemblerja.
Mi gremo dalje.
SolarCharger
 
Prispevkov: 1079
Pridružen: 20 Jan 2015, 21:58
Zahvalil se je: 87 krat
Prejel zahvalo: 103 krat
Uporabnika povabil: borisz
Število neizkoriščenih povabil: 54

Re: String - C jezik

OdgovorNapisal/-a VolkD » 23 Sep 2015, 23:13

Ja šele sedaj sem dojel, da se pogovarjamo o različnih stvareh.
Nikakor nisem mogel vedeti, da se pogovarjate o dinamičnih alokacijah, ki so za PC nekaj sicer običajnega, za mikrokontrolerje jih pa praktično ni.

Ja če tega ne sproščaš pravilno boš pa prej ali slej naletel na hude težave, saj je samo stvar tega kdaj nabereš dovolj iteracij, ki zavzamejo spomin, sprostijo ga pa ne, da se nabere tega več kot PC zmore. Ampak tole je že "višja matematika" in jo je težko trpat v mikrokontrolerje.
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a IgorK » 23 Sep 2015, 23:13

SolarCharger, nisi razumel.

Po svoje ima VolkD prav, če imaš program ki za sabo ne sprošča pomnilnika in ga zaženeš 3x dnevno ter nato vsak večer ugasneš računalnik, potem ne bo težav. Ko pa gre za programe, ki laufajo 24/7 in med delovanjem ne čistijo tega, kar bi morali, potem bo slej kot prej prišlo do kraha sistema.

Je pa to offtopic in bi bilo dobro temo razdeliti.
IgorK
 
Prispevkov: 813
Pridružen: 20 Feb 2015, 00:08
Kraj: Rače
Zahvalil se je: 5 krat
Prejel zahvalo: 174 krat
Uporabnika povabil: s56rir
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a IgorK » 23 Sep 2015, 23:19

Ampak v mikrokontrolerjih se dinamična alokacija pomnilnika še kako uporabljaja. No, vsaj jaz jo.
IgorK
 
Prispevkov: 813
Pridružen: 20 Feb 2015, 00:08
Kraj: Rače
Zahvalil se je: 5 krat
Prejel zahvalo: 174 krat
Uporabnika povabil: s56rir
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a VolkD » 23 Sep 2015, 23:36

IgorK je napisal/-a:Ampak v mikrokontrolerjih se dinamična alokacija pomnilnika še kako uporabljaja. No, vsaj jaz jo.
Na AVR-jih ?
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a IgorK » 24 Sep 2015, 00:07

Odvisno od programa in prevajalnika.
Z AVR-ji že dolgo nisem delal, pa tudi naredil sem samo nekaj enostavnih programov in ni bilo potrebe.

Trenutno delam s PIC24 in PIC32 in se mi zdi to nepogrešljivo. Recimo, dinamični meniji, računanje antialiasing-a grafa, krožnic, barvni prelivi v barih... Če imaš dosti takih screenov, ti kar hitro zmanjka spomina, če greš na globalne spremenljivke. Z dinamično alokacijo težav s spominom ni, ker itak prikazuješ samo en screen naenkrat in si rezerviraš, kolikor potrebuješ, potem pa ob izhodu sprostiš.
IgorK
 
Prispevkov: 813
Pridružen: 20 Feb 2015, 00:08
Kraj: Rače
Zahvalil se je: 5 krat
Prejel zahvalo: 174 krat
Uporabnika povabil: s56rir
Število neizkoriščenih povabil: 17

Re: String - C jezik

OdgovorNapisal/-a arksi » 24 Sep 2015, 07:33

Ojojoj, ste se razpisali. En kup postov, ampak zame skoraj ne uporabnih.

Spoštovani soforumaši, dajte najprej prebrati kaj nekdo napiše, potem pojdite na kavo in se malo nadihajte svežega zraka, šele nato odgovorite ;-).
Pa da ne bom narobe razumljen. Nikomur nič slabega......

arksi je napisal/-a:Tole kar sprašujem, bi uporabljal izključno za programiranje AVR mikrokontrolerjev.


Vprašanje je bilo čisto začetniško in sicer o uporabi stringov v jeziku C. Vi pa ste potem odaljili povsem drugam in ne nek visok nivo programiranja.
A nebi raje napisali kakšen stavek o uporabi stringov v C.?

No, če bo kdo še kaj napisal okoli uporabe stringov bom vesel, če pa ne, pa tudi nič zato.

Hvala in lep dan!

LP
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a Kroko » 24 Sep 2015, 08:23

Vse se je začelo, ko si vprašal kako se string "izbriše". Kar nekaj nas je, ki si pod besedo "izbriše" predstavljamo tudi, da je potrebno spomin sprostiti.
string[0] = 0; tega ne naredi in string ni v resnici izbrisan.

Za naš entuziazem so verjetno krive izkušnje. Dobro se spominjam se neprespanih noči, ko sem po kodi lovil memory leake.

Sem pa našel zanimiv link o C stringih:
http://www.buzzfeed.com/juliegerstein/the-c-string-makes-the-average-thong-look-like-granny-pantie#.ijV96wvO4
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a arksi » 24 Sep 2015, 09:49



Hehe, ti pa si za štose :D ....

Kroko je napisal/-a:Vse se je začelo, ko si vprašal kako se string "izbriše". Kar nekaj nas je, ki si pod besedo "izbriše" predstavljamo tudi, da je potrebno spomin sprostiti.
string[0] = 0; tega ne naredi in string ni v resnici izbrisan.
Da ne bom off......Kroko kako pa se ga v resnici izbriše oz. izprazni prostor?

Uh, kako bi ti bil hvaležen, ko bi tale stavek že na začetku napisal in potem bi debatirali naprej.
Kako pa naj vpraša začetnik, ki je začel "tipati" po C jeziku? Marsikaj mu/mi ni jasno, zato se vpraša. Vas po nekako razumem, da se vam ne ljubi ukvarjati z nekimi začetniki, ker ste v veliki večini "stari mački".
Dajte se spomniti vaših začetkov, kako vas je osrečilo, ko je zablinkala ledica. No, na tem dejstvu nas poizkusite razumeti in po svojih močeh pomagati.

V eni drugi temi je borisz lepo napisal, da si je potrebno pomagati med seboj. Pa, če on pravi tako, potem bo že držalo ;-).

In bom spet ponovil. Dajmo se ukvarjati z tehniko in elektroniko ne pa "mlatiti prazne slame" v forumih ala "rešimo svet" in podobnih.

LP
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a VolkD » 24 Sep 2015, 10:52

arksi je napisal/-a:
Kroko je napisal/-a:Vse se je začelo, ko si vprašal kako se string "izbriše". Kar nekaj nas je, ki si pod besedo "izbriše" predstavljamo tudi, da je potrebno spomin sprostiti.
string[0] = 0; tega ne naredi in string ni v resnici izbrisan.
Da ne bom off......Kroko kako pa se ga v resnici izbriše oz. izprazni prostor?


Ja pri razlaganju stringov smo spustili precej tega. V glavnem okrog lokacije takega stringa. Bom poskušal kar se da enostavno povedati. Sicer pa to velja za vse spremenljivke, ne le za stringe.

Vse je odvisno od tega kje spremenljivko, ki ta strig vsebuje definiramo. Kje jo bomo definirali pa je odvisno od tega kaj potrebujemo.Pri nadaljni razlagi bo verjetno SolarCharger ponorel od veselja. Tisti, ki se dajejo z assemblerjem to problematiko razumejo že v samem štartu, ker brez tega sploh ne morejo ničesar pametnega narediti.

Torej, če potrebujemo nek string v glavni zanki programa, to je tista, ki se pri mikrokontrolerjih nikoli ne konča, potem moramo spremenljivko definirati v delu glavnega programa. To pa pomeni, da bo stalno zavzemala prostor. Tega prostora se ne da sprostiti. Lahko sicer sleparimo, in isto lokacijo uporabimo še za kakšen drug namen (raje ne počnimo tega, ker je to potencialen vir težko rešljivih napak). Je pa to recimo način, da neko lokacijo ki jo uporabimo v postopku inicializacije, uporabljamo kasneje za nekaj drugega.

Če nek string/ali pa drug tip spremenkjivke potrebujemo le v enem delu programa, potem je smiselno ta del programa napisati kot proceduro/funkcijo. V tem delu programa potem definiramo to spremenljivko. Spremenljivka zavzema prostor le dokler je tok programa v tej proceduri/funkciji . Ko gre tok programa iz te funkcije se tudi prostor te spremenljivke sprosti. In obratno, vsakič, ko zaide programski tok v to proceduro/funkcijo, ta spremenljivka zasede na novo prostor. Pri tem ni nujno, da je to isti prostor kot prejšnič. To pa pomeni, da se podatki take spremenljivke ne ohranijo potem, ko smo zapustili proceduro. Uporaba take spremenljivke zunaj te procedure/funkcije torej ni mogoča. Jasno, da so podatki na lokaciji te spremenljivke, takoj, ko smo zapustili proceduro, še vedno tam. Obstaja tudi tricky način, da izvemo lokacijo in tako pridemo do njih. Vendar se tega ne počne, ker jih že v naslednjem trenutku lahko prepiše neka druga spremenljivka.

Obstaja še kup drugih bolj sofisticiranih načinov alokacije in sproščanja spremenljivk.
Ampak za začetek bo to dovolj.

Še malo o tem, kaj se v resnici dogaja.
Pri definiciji spremenljivke v glavnem programu, taka spremenljivka dobi nek naslov v RAM-u. Ta naslov je potem znan celemu programu in vsem njegovim proceduram in funkcijam. Ta naslov se potem ves čas izvajanja programa ne spremeni!

Da bi razložil kaj se zgodi ko definiramo spremenljivko v proceduri moram povedati kaj je sklad.
Sklad je nek prostor v RAM-u. V ta prostor odlagamo podatke. Enega nad drugega. Vedno si beležimo kje se nagaja vrh. In seveda obratno. Jemljemo podatke, a so dosegljivi vedno samo z vrha (lahko z ofsetom).
Ko pokličemo neko proceduro in se bo ta izvedla, se mora programski tok vrniti nazaj tja od koder smo jo poklicali. No točneje, natanko za to lokacijo. Da bi sploh imeli to informacijo jo moramo nekam shraniti. Shranimo jo na sklad. Naj enostavnejše procedure torej ob klicu porabijo nekaj spomina, ki služi temu, da ob izhodu vemo kam se vrniti.
Če v taki enostavni proceduri definiramo spremenljivko, potem ta spremenljivka običajno zavzame prostor takoj nad informacijo o tem kam se vrniti.

Ko procedura konča svoje delo in se vrne v del programa od koder smo jo poklicali, se informacija kje je vrh sklada seveda spremeni. Vrne se na vrednost, kakršna je bila pred klicanjem procedure. Na ta način se tudi sprosti RAM, ki ga je zavzela tako definirana spremenljivka.

Kdor dobro pozna kako deluje sklad, lahko seveda s tem tudi manipulira. Lahko tudi na načine, da se zgodi nekaj, kar je na prvi pogled težko razumljivo. Če recimo v neki proceduri spremenimo naslov za vračanje zapisan na skladu, potem se ob koncu take procedure ne bomo več vrnili tja od koder je bila poklicana, ampak nekam povsem drugam. Tega se načeloma ne počne, ker je to izjemno težko kontrolirati. Je pa prav, da vemo, da se to lahko zgodi. In lahko se zgodi povsem nenamenoma.
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a Proteus » 24 Sep 2015, 11:22

VolkD je napisal/-a:
IgorK je napisal/-a:Ampak v mikrokontrolerjih se dinamična alokacija pomnilnika še kako uporabljaja. No, vsaj jaz jo.
Na AVR-jih ?

Ne gre pozabiti tudi na to, da večina stringov v uC itak ni v ramu.
Uporabniški avatar
Proteus
 
Prispevkov: 3363
Pridružen: 18 Jan 2015, 01:31
Kraj: Planet Zemlja
Zahvalil se je: 361 krat
Prejel zahvalo: 737 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 136

Re: String - C jezik

OdgovorNapisal/-a arksi » 24 Sep 2015, 12:48

Mogoče bi bilo pa dobro, seveda, če je čas, če bi se tole predavanje spet nadaljevalo.
Kot vidim je eno predavanje že šlo skozi. Zdi se mi, da je bilo kar obsežno. Mogoče za naprej skromen nasvet, da za začetnike ne bi bilo tako obsežno. No, to je samo moje mnenje. Drugače pa nič ne "forsiram", da bi se sedaj tole moralo nadaljevati....
Nekako je bilo "obljubljeno" nadaljevanje. Mogoče bo, in bi še koga zanimalo.?

LP
arksi
 
Prispevkov: 945
Pridružen: 21 Jan 2015, 08:01
Kraj: Dolenjska
Zahvalil se je: 1816 krat
Prejel zahvalo: 167 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 19

Re: String - C jezik

OdgovorNapisal/-a VolkD » 24 Sep 2015, 12:55

arksi je napisal/-a:Mogoče bi bilo pa dobro, seveda, če je čas, če bi se tole predavanje spet nadaljevalo.
Kot vidim je eno predavanje že šlo skozi. Zdi se mi, da je bilo kar obsežno. Mogoče za naprej skromen nasvet, da za začetnike ne bi bilo tako obsežno. No, to je samo moje mnenje. Drugače pa nič ne "forsiram", da bi se sedaj tole moralo nadaljevati....
Nekako je bilo "obljubljeno" nadaljevanje. Mogoče bo, in bi še koga zanimalo.?

Se bom potrudil.
Dokler bodo ljudje mislili, da živali ne čutijo bolečine, bodo živali čutile, da ljudje ne mislijowww.S5tech.net
Uporabniški avatar
VolkD
Administratorji strani
 
Prispevkov: 68037
Pridružen: 29 Dec 2014, 20:49
Kraj: Kačiče (Divača)
Zahvalil se je: 20949 krat
Prejel zahvalo: 10681 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a Kroko » 24 Sep 2015, 13:35

Mogoče ne bi bilo napačno definirati kaj string v C-ju sploh je.

V C-ju stringi kot tip v bistvu sploh ne obstajajo :_CR

Poznamo karakterje (char) katere lahko združimo v nize (array). Nizi zasedejo nek spomin. To pomeni, da se nahajajo na nekem naslovu.
Potem obstajajo funkcije, ki so namenjene manipulacijam z takimi nizi (strcpy, strcat,...). Te funkcije zelo olajšajo delo z nizi.
Problem se pojavi, ker je v nekem nizu (rezerviranem spominu) lahko več ali manj uporabljenih znakov. Besede so lahko deljše ali krajše.
Zgoraj omenjene funkcije nimajo pojma, koliko karakterjev je dejansko uporabljenih. Zato so določili končni znak \0 (null, nič). Šele po tej "konvenciji" lahko govorimo o null terminated stringih. Se pravi, to niso tipi - to je pravilo, kako so nizi obravnavani.

Za določanje spomina in sproščanje spomina tako veljajo enaka pravila kot za vse nize. Na tem mestu bi bilo verjetno potrebno povedati kaj o kazalcih vendar se bojim, da bi bilo prehudo.

Višji jeziki od C stringe obravnavajo drugače. V Delphiju je za to skrbel sam prevajalnik (compiler magic). Objektni jeziki imajo stringe definirane kot razrede. V C++ na primer poznamo std::string.
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: String - C jezik

OdgovorNapisal/-a Kroko » 24 Sep 2015, 13:51

Kakšen bi bil interes, da pripravim online "malo šolo" C-ja?
http://www.planet-cnc.com Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 6153
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 770 krat
Prejel zahvalo: 2445 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Naslednja

Vrni se na C in sorodni jeziki

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost