Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Inicijalizacija char polja

[es] :: C/C++ programiranje :: C/C++ za početnike :: Inicijalizacija char polja

[ Pregleda: 3580 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

itf
Zagreb

Član broj: 59794
Poruke: 993
*.adsl.net.t-com.hr.



+9 Profil

icon Inicijalizacija char polja01.12.2008. u 00:10 - pre 187 meseci
Ako znamo da se deklaracijom

char niz[] = "123";

rezervira ukupno 4 byte-a za niz, što se onda dogodi kada napravimo tu deklaraciju i inicijalizaciju preko pokazivača (što je također legalno)?

Code:
char* x = "123";  // gdje je ovo spremljeno? x je automatski alociran?
x = "ABC123";  // realokacija?
cout << x[100];


Zanimljivo je da mi program ne puca niti na drugoj niti na trećoj liniji ovog koda, pa mi zato nije jasno kako je to moguće. Što se onda dogodi na drugoj liniji koda? To bi trebala biti logička greška jer memorija nije nigdje alocirana, niti se koristila funkcija strcpy.. zar ne?

[Ovu poruku je menjao itf dana 01.12.2008. u 01:23 GMT+1]
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
62.189.100.*



+1 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 14:39 - pre 187 meseci
Prvi slucaj alocira memoriju za niz karaktera a drugi ne.
x oba puta pokazuje na staticki alociran niz znakova, prvo na 123 a potom na ABC123, tj. dodeljena mu je adresa datih string literala. Kada se zavrsi tekuci blok i 123 i ABC123 budu unisteni, x ce (ako i sam ne bude unisten) pokazivati na to parce memorije koje tada vec sadrzi random podatke. Zato ovo ne treba raditi.
Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
161.53.237.*



+9 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 15:31 - pre 187 meseci
hoćeš reći da se on 2 puta statički alocirao tj. prvo na 123 a potom na ABC123? Meni je jasno što se događa u prvoj liniji koda, ali ova druga mi je problematična i svakako bi trebala biti pogrešna jer veličina niza je već određena prvom inicijalizacijom (pri deklaraciji).
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 3453

Jabber: djoka_l


+1462 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 16:09 - pre 187 meseci
Ako ovaj deo koda generišeš, kompajler će predvideti 4 bajta za prvi string ('1', '2', '3', '\0'), 4 bajta za pokazivač x (ako je mašina 32 bitna) i 7 bajtova za drugi string. Ti su stringovi statički definisani u DATA segmentu (može i na steku ali to nije bitno), tj. 11 bajtova je već odvojeno za smeštaj pointera i 2 niza znakova. Dodela statičkog string literara pokazatelju će samo promeniti adresu na koju pokazivač pokazuje, a neće se raditi nikakva alokacija memorije (ona je već odrađena u procesu kompajliranja).
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
62.189.100.*



+1 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 16:10 - pre 187 meseci
Ne, "123" i "ABC123" su staticki alocirani, a x u oba slucaja samo pokazuje na njih, nema alokacije za njega. Dakle,
Code:

char* x = "123";

ne alocira niz za x, samo se alocira pokazivac koji pokazuje na staticki string.

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

itf
Zagreb

Član broj: 59794
Poruke: 993
*.adsl.net.t-com.hr.



+9 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 16:59 - pre 187 meseci
Zar onda zapravo nije napravljen memory leak ako prvo alociraš pokazivač x tako da pokazuje na jedan niz, a zatim ga preusmjeriš na drugi niz. Ovaj prvi niz se sam dealocirao?
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.dynamic.sbb.rs.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 20:09 - pre 187 meseci
^
Citat:

Zar onda zapravo nije napravljen memory leak ako prvo alociraš pokazivač x tako da pokazuje na jedan niz, a zatim ga preusmjeriš na drugi niz. Ovaj prvi niz se sam dealocirao?

Zapravo, nije X preusmereno. Ako se ispise "adresa od X" (umesto sadrzaja), ona je uvek ona koja je jednom vec dodeljena prilikom: char* x = "123";. Nije se promenila. Promenio se samo sadrzaj string literala, a kako je i da li je prethodni sadrzaj string literala u data segmentu unisten, pojma nemam.

Drugim recima, nije mi poznato kako se unistava 123:
Code:

char *ptr1 = "123";
cout << ptr1[0] << ptr1[1] << ptr1[2];

ptr1 = "X";
cout << ptr1[0] << ptr1[1] << ptr1[2]; // <--- ne ispise se 3

... jer se izgleda ne radi o overwrite-u, barem sudeci prema ovom primeru koga sam na brzinu isprobao.


Standard ISO/IEC 14882 kao i The C++ Programming Language, Third Edition by Bjarne Stroustrup donekle opisuju taj slucaj u sekcijama posvecenim String literal-ima.

Poenta je da string literal treba da je const:
Citat:

...
"An ordinary string literal has type “array of n const char” and static storage duration [...]"
...
"The type of a string literal is ''array of the appropriate number of const characters'' [...]"
...

... sto je najbolje da se eksplicitno i navede (valjda ovako: char * const ptr1 = "123").

Dalje, kaze se:
Citat:

...
"The effect of attempting to modify a string literal is undefined."
...

Dakle, efekat pokusaja menjanja string literala je nedefinisan, sto je potkrepljeno primerom da dva string literala istog sadrzaja (teksta) mogu da dele istu adresu, bez obzira sto su uvedeni sa razlicitim pokazivacima!!!

Razlog sto je pokusaj menjanja dozvoljen, moze se opravdati sa cinjenicom:
Citat:

A string literal can be assigned to a char *. This is allowed because in previous definations of C and C++, the type of a string literal was char *. Allowing the assignment of a string literal to a char * ensures that millions of lines of C and C++ remain valid.


Konacno:
Citat:

"Implicit conversion of a string literal to a (non-const) char* is deprecated. You should use array of char or avoid assignment of string literals."


Ako neko ima nesto potpunije neka napise.
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
94.189.253.*



+1 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 20:40 - pre 187 meseci
I na FAQ za C tvrde slično za (ne)promenljivost literala:
http://c-faq.com/decl/strlitinit.html
http://c-faq.com/ansi/strlitnotconst.html

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

Eurora3D Team
Nebojsa - Programer & Vodja tima
Beograd

Član broj: 120376
Poruke: 900
*.dynamic.sbb.rs.



+7 Profil

icon Re: Inicijalizacija char polja01.12.2008. u 23:43 - pre 187 meseci
Moje vidjenje , stringovi se pri kompajlovanju upisuju i PE fajl (u odredjeni segment) ... kad se proces pokene i fajl se ucita, stringovi su se nasli na odredjenim adresama u virtuelnoj memoriji (tacno se zna na kojim).
Ovde u kodu pointeru su jednostavno dodeljene dve adrese jedna za drugom i to je to ... jedino sto se menja u celom programu je vrednost pointera a memorija stingova ostaje ista celo vreme.
To odgovara ovom citatu koji je okacio X Files
"
"An ordinary string literal has type “array of n const char” and static storage duration [...]"
...
"The type of a string literal is ''array of the appropriate number of const characters'' [...]"
"
ili sto rece @karas " "123" i "ABC123" su staticki alocirani"

Mali test ... adrese sam procitao u debugeru pa prekompajlovao
Code:

#include<iostream>
using namespace std;

int main ()
{
   char* x = "123"; 
   // ^ Ovde je x 0x0043202c , znaci  "123" pocinje na 0x0043202c
   x = "ABC123"; 
   // ^ Ovde je x 0x00431024 , znaci "ABC123" pocinje na 0x00431024

   //ima i ovoga ... ispisuje nesto iz tog segmenta
   char* mem = (char*)0x00431024; //  "ABC123"
   cout << mem << endl; // ispisuje  "ABC123"
   //ali ovo ne prolazi ... segment ne moze da se menja
   *mem = 'A'; // <- ovde se prekida
    cout << mem << endl;
   //ni ovo
   *x ='A';

   system("pause");
   return 0;
}

 
Odgovor na temu

tkaranovic
Tomislav Karanović
Beograd

Član broj: 220507
Poruke: 307



+18 Profil

icon Re: Inicijalizacija char polja06.09.2009. u 04:47 - pre 178 meseci
Dodajem malo konkretnog koda pisanog sa VS2008:

Code:

  char *x = "123";  // u pointer x upisuje pokazivac na: (const char[3]) "123"
  int mem123 = (int)(void*)x;  //mem123 cuva adresu od "123"
  x = "ABC";  // u x upisuje pokazivac na "ABC"
  int memABC = (int)(void*)x;  //memABC cuva adresu od "ABC"
  cout << x << endl;  //pise "ABC" a moze da se vrati i na prvu lokaciju:
  x = (char*)mem123; // u x vraca pokazivac na "123"
  cout << x << endl;  //pise "123"

  //adrese:
  cout << &x << endl;  // x je pointer sa svojom adresom u kojem se mogu zamenjivati pokazivaci adresa:
  cout << (void*)mem123 << endl;  // "123"
  cout << (void*)memABC << endl;  // "ABC"

  //moze i sam pokazivac (adresa memoriske lokacije) da postoji:
  int ConstLiteral = (int)(void*)"ConstLiteral";
  cout << ((char*)ConstLiteral)[0] << endl;  //pise "C"
  cout << (char*)ConstLiteral << endl;  //pise "ConstLiteral"
  
  //ili ovako:
  int CL4 = (int)(const char[4]) "[4]";
  cout << (char*)CL4 << endl;  //pise "[4]"  
 
Odgovor na temu

[es] :: C/C++ programiranje :: C/C++ za početnike :: Inicijalizacija char polja

[ Pregleda: 3580 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.