VS2010 nu initializeaza pointeri cu NULL?

Intrebari despre programarea cu VC++ incluzand mediul de dezvoltare, instalare, setari, debugger, compilator, linker si documentatie.

VS2010 nu initializeaza pointeri cu NULL?

Mesajde u0m3 » 04 Dec 2009, 21:10

Am intalnit aceasta problema in implementarea listelor inlantuite prin structuri. A se considera urmatorul cod:
Cod: Selectaţi tot
#pragma once
template<typename _T>
class CLinkedList
{
private:
   struct ELEM
   {
      _T m_value;
      ELEM* m_pPrevElem;
      ELEM(_T v, ELEM* prev): m_value(v), m_pPrevElem(prev){};
   };

   ELEM* m_pCurElem;
protected:
public:
   CLinkedList()
   {
   };

   virtual ~CLinkedList()
   {
      ELEM* pCurElem = m_pCurElem;
      ELEM* pNextElem;
      while(pCurElem)
      {
         pNextElem = pCurElem->m_pPrevElem;
         delete pCurElem;
         pCurElem = pNextElem;
      }
   };

   void push(_T val)
   {
      ELEM* p = new ELEM(val, m_pCurElem);
      m_pCurElem = p;
   };

   _T pop(void)
   {
      if(!m_pCurElem)
         throw _T("ERROR");   // custom exception class placeholder
      _T ret = m_pCurElem->m_value;
      ELEM* p = m_pCurElem;
      m_pCurElem = p->m_pPrevElem;
      delete p;
      return ret;
   };
};
Problema este ca in modul Debug ultimul m_pCurElem are valoarea 0xccccccc in loc de 0x0, iar in momentul distrugerii, loop-ul while nu iese si se incearca accesarea unui parametru al unui pointer tip struct, inexistent => exception.


Acesta este comportamentul normal (implicand ca eu sunt fortat sa initializez m_pCurElem cu NULL in constructor) sau este o "chichita" VS2010?


Multumesc anticipat pentru indicatii.
Old-School: If at first you don't succeed, try and try again.
New-School: If at first you don't succeed, destroy every evidence that you have ever tried.
Citate nostime:
  1. Mintile umane sunt ca parasutele... Functioneaza doar daca sunt deschise.
  2. Light travels faster than sound, that's why some people seem Bright ...... untill they Speak...
u0m3
Membru
Membru
 
Mesaje: 75
Membru din: 21 Dec 2008, 19:11

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Silviu Ardelean » 04 Dec 2009, 21:32

Unde aloci tu memorie pentru m_pCurElem? In codul tau, eu nu vad nici un:
Cod: Selectaţi tot
m_pCurElem = new ELEM(v, prev);
Avatar utilizator
Silviu Ardelean
Membru++
Membru++
 
Mesaje: 938
Membru din: 12 Iul 2007, 09:22
Localitate: Timisoara

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde u0m3 » 04 Dec 2009, 21:48

In push(_T val).
Chiar m_pCurElem = new ELEM(v, prev) nu ai cum sa vezi, acesta fiind si scopul implementarii: de fiecare data cand adaugi un element in lista/stiva, creezi o noua structura careia ii specifici ca elementul precedent este cel curent, apoi cel curent devine cel pe care tocmai l-am creat.

Am vazut o impementare asemanatoare intr-un alocator de memorie tip arena (sau cel putin asa mi-a zis cineva ca se numeste). Din acest motiv sunt nedumerit: comform acelui exemplu, ar trebui sa mearga loop-ul while din destructor, doar ca la mine arunca o exceptie conform careia accesez o zona de memorie interzisa ("Access violation reading location ...").
Ultima oară modificat de u0m3 pe 04 Dec 2009, 21:56, modificat 1 dată în total.
Old-School: If at first you don't succeed, try and try again.
New-School: If at first you don't succeed, destroy every evidence that you have ever tried.
Citate nostime:
  1. Mintile umane sunt ca parasutele... Functioneaza doar daca sunt deschise.
  2. Light travels faster than sound, that's why some people seem Bright ...... untill they Speak...
u0m3
Membru
Membru
 
Mesaje: 75
Membru din: 21 Dec 2008, 19:11

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde jos8cal » 04 Dec 2009, 21:54

Pai de ce sa aiba valoarea 0x0 si nu 0xFF342121 in Debug? Valoarea din variabila aia este problema ta, tu ii dai un sens (Bine, mai putin daca esti in .NET, ca acolo este the land of milk and honey). So, nu e nicio chichita VS2010, trebuie sa-ti initializezi variabilele. Pune m_pCurElem = 0 in constructor si gata.

LE: Si btw, valoarea 0xcccccc are un sens, nu e random shit, tocmai din motivul asta exista modul Debug.

0xFDFDFDFD No man's land (normally outside of a process)
0xDDDDDDDD Freed memory
0xCDCDCDCD Uninitialized (global)
0xCCCCCCCC Uninitialized locals (on the stack)
Ultima oară modificat de jos8cal pe 04 Dec 2009, 21:58, modificat 1 dată în total.
Avatar utilizator
jos8cal
Banned
Banned
 
Mesaje: 86
Membru din: 16 Feb 2008, 02:01

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Ovidiu Cucu » 04 Dec 2009, 21:56

u0m3 scrie:VS2010 nu initializeaza pointeri cu NULL?

NU.
Daca ai folosi o scula de analiza statica de cod aceasta ar face spume la gura daca ti-ar gasi variabile neinitalizate (pointerul este si el o variabila).
Pentru o variabila membru, te obliga chiar sa o initializazi in lista de initializare a constructorului, indiferent ce faci cu ea mai departe.
In cazul tau trebuie sa scrii
Cod: Selectaţi tot
   CLinkedList() : m_pCurElem(NULL)
   {
   };

In cazul cand nu faci aceasta, in versiunea release e posibil ca, in functie de sistemul de operare pe care ruleaza, o variabila neinitializata sa se afle undeva intr-o zona de memorie umpluta dinainte cu zerouri dar tot atat de bine sa contina te miri ce altceva (in limbajul programatorului roman se spune "carcalaci").
In versiunea debug, variabilele neinitializate se umplu cu 0xCC-uri tocmai ca, aruncand o privire in debugger sa-ti dai seama c-ai uitat ceva...
Vezi articolasul acesta: http://www.codexpert.ro/articole.php?id=7

Deci, regula #0 a variabilelor:
Poa sa ninga, poa sa ploua
Sa se rupa ****-n doua
Nu lasa neinitializata variabila cea noua!
. :D ;)
Ovidiu Cucu
Microsoft MVP - Visual C++
Avatar utilizator
Ovidiu Cucu
Fondator
Fondator
 
Mesaje: 2218
Membru din: 11 Iul 2007, 16:10
Localitate: Iasi

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Marius Bancila » 04 Dec 2009, 22:32

Nu are nici o legatura cu VS 2010. Asa e de cand lumea. Valorile alea "ciudate" le-am explicat la inceputul acestui articol: http://www.codeguru.com/cpp/w-p/win32/t ... php/c9535/.

In release vei avea valorile initializate cu 0, dar ar trebui sa faci tu explicit asta.

PS: ce imi place la alte limbaje ca C# e ca initializeaza implicit orice variabile cu valorile default pt. tipul respectiv, indiferent de setarile de build. Standardul C++ nu specifica nimic de genul acesta, din care cauza exista acest comportament diferit in VC++ in DEBUG si RELEASE, depinzand de seatarile de compilare.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog
Avatar utilizator
Marius Bancila
Fondator
Fondator
 
Mesaje: 1777
Membru din: 11 Iul 2007, 11:45
Localitate: Timisoara

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Ovidiu Cucu » 04 Dec 2009, 23:13

Marius Bancila scrie:PS: ce imi place la alte limbaje ca C# e ca initializeaza implicit orice variabile cu valorile default pt. tipul respectiv, indiferent de setarile de build. Standardul C++ nu specifica nimic de genul acesta, din care cauza exista acest comportament diferit in VC++ in DEBUG si RELEASE, depinzand de seatarile de compilare.

La vremea cand au pus bazele limbajului C, domnii Kernighan si Ritchie n-au gandit deloc rau cand au lasat posibilitatea programatorilor sa lase neinitializate variabilele (n-a indraznit sa-i contrazica nici Stroustrup si nici cei din comitetul de standardizare :)).
Dupa cum isi amintesc multi programatori de C++ si probabil chiar si cativa programatori de C#, in C variabilele locale se declara la inceput de bloc.
De exemplu
Cod: Selectaţi tot
{
   int sum;  /* usually, here sum is garbage on the stack */
   /* some code here */
   sum = a + b; /* sum takes a meaningful value */
   /* some other code here */
   printf("sum=%d", sum);
}

Daca in codul de mai sus compilatorul ar pune automat o valoare default, sa zicem 0, ar pune cel putin o instructine procesor care sa faca asta, logic fara rost, ducand la micsorarea performantei.

Din pacate, in practica programarii (mai binezis a "scrierii de cod" :)) s-au facut tone de greseli de genul
Cod: Selectaţi tot
{
   int sum;  /* usually, here sum is garbage on the stack */
   /* some code here */
   /* nothing like 'sum = ...' then sum is still garbage */
   printf("sum=%d", sum); /*print garbage*/
}

Cu pointerii treaba-i si mai naspa. Folosind pointeri nenitializati, avand te miri ce valori arbitrare, putem fi multumiti daca rezulta un "access violation", altfel Dumnezeu cu mila ce se poate intampla.

// Cat despre limbajele inalte (C#, VB, etc): intradevar ajuta programatori cascati sa nu greseasca si nici sa-si oboseasca capusorul si manutele cu initializarea variabilelor.
// Dar eu unul, nici nu indraznesc sa ma gandesc cat amar de instructini masina baga-n spate pentru asta. ;)
Ovidiu Cucu
Microsoft MVP - Visual C++
Avatar utilizator
Ovidiu Cucu
Fondator
Fondator
 
Mesaje: 2218
Membru din: 11 Iul 2007, 16:10
Localitate: Iasi

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Silviu Ardelean » 04 Dec 2009, 23:22

Ovidiu, daca tot ai amintit de analizatoare statice de cod, sa nu uitam ca acestea nu agreeaza declararea variabilelor neinitializate. :D
Avatar utilizator
Silviu Ardelean
Membru++
Membru++
 
Mesaje: 938
Membru din: 12 Iul 2007, 09:22
Localitate: Timisoara

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Ovidiu Cucu » 04 Dec 2009, 23:30

Silviu Ardelean scrie:Ovidiu, daca tot ai amintit de analizatoare statice de cod, sa nu uitam ca acestea nu agreeaza declararea variabilelor neinitializate. :D

"Nu agreeaza" e putin spus. Cred c-am zis si mai inainte. Turbeaza (ochi injectati, spume la gură, muşcă...). :biggrin:
Ovidiu Cucu
Microsoft MVP - Visual C++
Avatar utilizator
Ovidiu Cucu
Fondator
Fondator
 
Mesaje: 2218
Membru din: 11 Iul 2007, 16:10
Localitate: Iasi

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Silviu Ardelean » 04 Dec 2009, 23:56

Ovidiu Cucu scrie:
Silviu Ardelean scrie:Ovidiu, daca tot ai amintit de analizatoare statice de cod, sa nu uitam ca acestea nu agreeaza declararea variabilelor neinitializate. :D

"Nu agreeaza" e putin spus. Cred c-am zis si mai inainte. Turbeaza (ochi injectati, spume la gură, muşcă...). :biggrin:


Tocmai deaia am amintit de situatie. :twisted:
Avatar utilizator
Silviu Ardelean
Membru++
Membru++
 
Mesaje: 938
Membru din: 12 Iul 2007, 09:22
Localitate: Timisoara

Re: VS2010 nu initializeaza pointeri cu NULL?

Mesajde Marius Bancila » 06 Dec 2009, 21:20

Daca in codul de mai sus compilatorul ar pune automat o valoare default, sa zicem 0, ar pune cel putin o instructine procesor care sa faca asta, logic fara rost, ducand la micsorarea performantei.

Intradevar, la inceputul anilor '70 asta era important. Acum nimeni nu se mai gandeste la asa ceva, pt. ca nu mai are sens. Simplitatea si corectitudinea, programatorul sa aiba cat mai putine sanse sa faca greseli, sunt lucrurile care conteaza.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog
Avatar utilizator
Marius Bancila
Fondator
Fondator
 
Mesaje: 1777
Membru din: 11 Iul 2007, 11:45
Localitate: Timisoara


Înapoi la Visual C++

Cine este conectat

Utilizatorii ce navighează pe acest forum: Niciun utilizator înregistrat şi 1 vizitator