Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2001
    Messaggi
    372

    [c++] variabile puntatore e new/delete: perchè non ho un memory leak??

    codeblock 8.02
    compilando con gcc 3.4.5 sotto Vista

    ho fatto questo piccolo test che mi lascia dei dubbi:


    1)
    codice:
    int x=50;
       
       int *p_x=NULL;
       
       p_x=new int(20);  //alloco memeoria x un intero ed assegno indirizzo a p_x ed inizializzo
    
       p_x=&x;  	     //non ho usato delete x liberare memoria prima di assegnare indirizzo   di x: non è un errore??
    
       *p_x=100;
    perchè non è segnalato in debug


    2) successivamente ho aggiunto:

    codice:
       delete p_x;
    
       cout << *p_x >> endl;
    stampa comunque 100 é giusto ??!!??



    3) se uso delete vado in segmentation fault dopo alcune volte che si esegue ripetutamente la funzione, ne riporto sinteticamente il corpo:
    codice:
     
      void InitCb () {
    
       int *Id=new int(0);
    
       ..
       ..	   
       
       *Id=4;
       
       while () {  //ciclo righe della tabella
          int *i=new int(0);				//segmentation fault
          while () { // ciclo colonne della riga
             SendDlgItemMessage();
             *i+=1;
          }
          delete i;
          SQLFetch()
       }
    
       delete Id;
    
       ..
       ..
       
       int *Item=new int(0);
       if() 
          *Item=SendDlgItemMessage();
       SendDlgItemMessage();
    
       delete Item;
      
      }

  2. #2
    1 - no, non è un errore che il compilatore ti evidenzi. Hai semplicemente perso la memoria allocata con p_x=new int(20), e non hai più la possibilità di rilasciarla poichè non puoi più risalire al suo indirizzo.
    2 - delete p_x a questo punto è completamente sbagliato perchè stai rilasciando una memoria che non hai allocato dinamicamente. Quello che era però contenuto in quella casella di memoria non è tuttavia toccato e rimane quello che era prima e penso che nessuno lo modificherà più perchè non fa parte della memoria dinamica. Hai semplicemente pasticciato.
    3 - new int (0); non ho idea di cosa può fare il compilatore con una simile richiesta, ma è sbagliato e non mi meraviglia che quando cerchi di risasciare una memoria non allocata ti vada in errore di runtime
    ciao
    sergio

  3. #3
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da mondobimbi
    3 - new int (0); non ho idea di cosa può fare il compilatore con una simile richiesta, ma è sbagliato e non mi meraviglia che quando cerchi di risasciare una memoria non allocata ti vada in errore di runtime
    ciao
    sergio
    No, non è sbagliato. Semplicemente crea un int e lo inizializza a 0 con un solo passaggio.

  4. #4
    hai ragione, ho pensato fossero parentesi quadrate.

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2001
    Messaggi
    372
    Originariamente inviato da shodan
    No, non è sbagliato. Semplicemente crea un int e lo inizializza a 0 con un solo passaggio.
    diciamo che è la forma "contratta/sintetica" anzichè avere + di una riga!

    ma per il punto 3) perchè va in segmentation fault in int *Id=new int(0); dopo alcune volte anche se hai rilasciato memoria allocata??? :master:

  6. #6
    non penso dipenda da quello, circoscrivi l'errore, per esempio questo codice dà errore ?
    codice:
    int main ()
    {
       while (1) {  
    	int *i=new int(0);	
    	delete i;
       }
    
       return (0);	
    
    }
    penso di no, aggiungi via via le altre funzioni e guarda quando hai l'errore
    ciao
    sergio

  7. #7
    Utente di HTML.it
    Registrato dal
    Apr 2001
    Messaggi
    372
    [QUOTE}
    penso di no, aggiungi via via le altre funzioni e guarda quando hai l'errore
    ciao
    sergio [/QUOTE]

    questo è quello che ho potuto fare:

    deallocando Id va in SIGSEGV quando si rialloca Id:

    codice:
    void InitCb(HWND hwnd, char from, int mItem, int IDCtrl, char *StrFind)
    {
        RETCODE rc;
        SQLHSTMT stmtCb;
        char *StaSql=NULL;   ///QUI DA ADDRESS OUT OF BOUNDS     
        int *Id=new int(0);  /// RIGA 22  SIGSEGV   
        SQLAllocHandle(SQL_HANDLE_STMT,dbc,&stmtCb);
    	if(from=='R') {	
    	  StaSql=(char*)GlobalAlloc(GPTR,strlen("call DBA.sp_CbRicerca( ? )")+1);
    	  StaSql="call DBA.sp_CbRicerca( ? )";
    	  SQLBindParameter(stmtCb,1,SQL_PARAM_INPUT,SQL_C_SSHORT,SQL_INTEGER,0,0,&mItem,0,NULL);
    	} else {
    	       *Id=IDCtrl;
    		if(mItem==12 && (IDCtrl==2107 || IDCtrl==2089)) {
    		   	char TitWin[40]; GetWindowText(hwnd,TitWin,40);
    			if(IDCtrl==2107) {
    				*Id=((strcmp(TitWin,"Nuovo numero fisso")==0 || strcmp(TitWin,"Aggiorna numero fisso")==0) ? 1 : 2);
    			} else if (IDCtrl==2089) {
    				*Id=((strcmp(TitWin,"Nuovo numero fisso")==0 || strcmp(TitWin,"Aggiorna numero fisso")==0) ? 3 : 4);
    			}
    		}
    		if((mItem==15 || mItem==16 || mItem==18) && (IDCtrl==2089 || IDCtrl==2092 || IDCtrl==2095 || IDCtrl==2098 || IDCtrl==2100)) {
    			*Id=3; 
    		} else if(mItem==18 && IDCtrl==2073) {
    			*Id=4; 
    		}
    		if(mItem==21 && (IDCtrl==3141 || IDCtrl==3144))//IDC_tyE IDC_tyU
    			*Id=3120; 
    		if(mItem==22)
    			*Id=5;
    		if((mItem==23 || mItem==25) && IDCtrl==3202) {
    			*Id=6;
    		} else if(mItem==24 && IDCtrl==3202) {
    			*Id=9;
    		} else if(mItem==23 && IDCtrl==3204) {
    			*Id=7;
    		} else if((mItem==24 || mItem==25) && IDCtrl==3204) {
    			*Id=8;
    		}
            StaSql=(char*)GlobalAlloc(GPTR,strlen("call DBA.sp_Cb( ? )")+1);
            StaSql="call DBA.sp_Cb( ? )";
    		SQLBindParameter(stmtCb,1,SQL_PARAM_INPUT,SQL_C_SSHORT,SQL_INTEGER,0,0,static_cast<void*>(Id),0,NULL);
    		if(IDCtrl!=3120 && IDCtrl!=3202 && IDCtrl!=3204 && IDCtrl==3141 && IDCtrl==3144 || (IDCtrl==2089 || IDCtrl==2092 || IDCtrl==2095 || IDCtrl==2098 || IDCtrl==2100)) //type mov in docp,doca; gir
    			SendDlgItemMessage(hwnd,IDCtrl,CB_ADDSTRING,0,(LPARAM)""); //item default
    	}
    	if(SQLExecDirect(stmtCb,(SQLCHAR*)StaSql,SQL_NTS)==SQL_SUCCESS) {
    	  rc=SQLFetch(stmtCb);
    	  RETCODE rc1;
    	  while(rc== SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO) {
    		int *i=new int(1);
    		while ((rc1=SQLGetData(stmtCb,*i,SQL_CHAR,szData1,50,&cbData1))==SQL_SUCCESS) {
    			SendDlgItemMessage(hwnd,IDCtrl,CB_ADDSTRING,0,(LPARAM)szData1);
                *i+=1;
    		}
    		delete i;  ///QUESTO OK
                     rc=SQLFetch(stmtCb);
    	  }
    	  if(IDCtrl==802 || IDCtrl==2089 || IDCtrl==2092 || IDCtrl==2095 || IDCtrl==2098 || IDCtrl==2100 || IDCtrl==2073 || IDCtrl==2110 || IDCtrl==2111 || IDCtrl==2085 || IDCtrl==2086)
    		  SendDlgItemMessage(hwnd,IDCtrl,CB_ADDSTRING,0,(LPARAM)"---new---");
    	} else {
    		ShowError(stmtCb);
    	}
        	///delete Id;  ///QUESTO NO VA IN SIGSEGV in linea 22 	SQLFreeHandle(SQL_HANDLE_STMT,stmtCb);
    
    	int *ItemSel=new int(0);  //1° item selezionato
    	if(StrFind!=NULL) {
    		*ItemSel=SendDlgItemMessage(hwnd,IDCtrl,CB_FINDSTRINGEXACT,(WPARAM)-1,(LPARAM)StrFind);
    	}
    	SendDlgItemMessage(hwnd,IDCtrl,CB_SETCURSEL,(WPARAM)*ItemSel, 0);
    	delete ItemSel;  ///QUESTO OK
    	GlobalFree(StaSql);
    }

    da debug inizialmente:

    Local variables
    StaSql= 0xa918 <Address 0xa918 out of bounds> ///PERCHE'

    Id = (int*)0x0
    ItemSel = (int*)0x4000400


    quando crea int *Id=new int(0);

    da debug:

    Local variables
    StaSql= 0x4380x8 "call DBA.sp_CbRicerca(?)"
    id = (int*)0xb73378
    ItemSel = (int*)0x4000400


    quando crea int *i=new int(1); assegna stesso indirizzo di ItemSel ancora da creare E' OK??
    da debug:

    Local variables
    i = (int*)0xb74228
    Id = (int*)0xb73378
    ItemSel = (int*)0xb74228


    quando crea int *ItemSel=new int(0);
    da debug:

    Local variables
    Id = (int*)0xb73378
    ItemSel = (int*)0xb73efc

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    codice:
    void InitCb(HWND hwnd, char from, int mItem, int IDCtrl, char *StrFind)
    {
    	  StaSql=(char*)GlobalAlloc(GPTR,strlen("call DBA.sp_CbRicerca( ? )")+1);
    	  StaSql="call DBA.sp_CbRicerca( ? )";
    }
    Ovvio che il compilatore si lamenti. Prima allochi un puntatore con una GlobalAlloc, poi assegni una const string allo stesso puntatore, perdendo quanto allocato prima, infine cerchi di distruggere il puntatore alla const string con una GlobalFree.
    Devi usare una strcpy ( o meglio la strncpy) per copiare la stringa.
    codice:
    void InitCb(HWND hwnd, char from, int mItem, int IDCtrl, char *StrFind)
    {
    	  StaSql=(char*)GlobalAlloc(GPTR,strlen("call DBA.sp_CbRicerca( ? )")+1);
    	  strcpy(StaSql,"call DBA.sp_CbRicerca( ? )");
             // o
             // strncpy(StaSql,"call DBA.sp_CbRicerca( ? )",strlen("call DBA.sp_CbRicerca( ? )");
    }

  9. #9
    Utente di HTML.it
    Registrato dal
    Apr 2001
    Messaggi
    372
    Originariamente inviato da shodan
    Ovvio che il compilatore si lamenti. Prima allochi un puntatore con una GlobalAlloc, poi assegni una const string allo stesso puntatore, perdendo quanto allocato prima, infine cerchi di distruggere il puntatore alla const string con una GlobalFree.
    purtroppo non è questo il problema

    si qui ti posso dar ragione con tutte le prove che ho fatto ... ho sbagliato, ma modificato come da tuo suggerimento ho sempre un segmentation fault a int *Id=new int(0); quando lo si riesegue dopo alcune volte;

    se voglio evitarlo devo commetare delete Id; anche farlo come ultima riga da problemi

    è normale che dealloco 2 variabili su 3 ????? PERCHE? solo su questa


    ripeto quanto indicato precedentemente:

    StaSql= 0xa918 <Address 0xa918 out of bounds> /// sempre prima di allocargli memoria è normale cosa significa???

    i = (int*)0xb74228
    ItemSel = (int*)0xb74228 //stesso indirizzo è normale


  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2001
    Messaggi
    372
    la cosa ancora + strana è che se eseguo l'applicazione non passandola da debug, ma attivo in monitor questo non segnala nulla e non solo faccio eseguire la funzione decine di volte e non solleva il problema :master:

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.