2010-10-27 45 views
0

je le code suivant, qui obtient une valeur de retour d'une fonction char*char * valeur est corrompu lors de l'affectation

cDestDrive = ReadFromRegistry(HKEY_CURRENT_USER,NDSPATH,szDestPathRoot); 

Je suis capable de lire la valeur à l'intérieur cDestDrive jusqu'au moment où je lui attribuer. Le moment où je suis lui attribuer:

CString strServerAddress = cDestDrive; 

se change la valeur de cDestDrive (corrompu) et je ne suis pas en mesure d'obtenir la valeur CString strServerAddres toute idée pourquoi cela se produit.

Edit: code pour lire à partir du Registre

char* CNDSShellExtender::ReadFromRegistry(HKEY hKey,LPCTSTR lpNDS,LPSTR lpRegKey) 
{ 

     HKEY hRegKey=NULL; 
     if(hKey==NULL || lpNDS==""||lpNDS==NULL||lpRegKey==""||lpRegKey==NULL) 
      MessageBox(NULL,"Reading from Registry Failed!Invalid Path", 
              _T("Network Drive Solution"), 
                  MB_ICONERROR); 

     LONG lOpenRes=RegOpenKey(hKey,lpNDS,&hRegKey); 

     if (lOpenRes!=ERROR_SUCCESS ||lpNDS==NULL) 
      MessageBox (NULL, "Can not Find Any Server to Connect", 
              _T("NDSShellExtension"), 
                MB_ICONERROR); 


     if(lOpenRes==ERROR_SUCCESS && lpNDS!=NULL) 
     { 
      TCHAR tSZValue[MAX_PATH] = {0}; 
      DWORD dwBufSize=MAX_PATH; 
      LONG lCloseOut; 
      LPBYTE lpStorage = reinterpret_cast<LPBYTE>(tSZValue); 
      char* cpRegKeyVal=tSZValue; 

      if (ERROR_SUCCESS == RegQueryValueEx(hRegKey,lpRegKey , 0, 0, (BYTE*)tSZValue, &dwBufSize)) 
       { 
        lCloseOut= RegCloseKey(hRegKey); 
        if (lCloseOut != ERROR_SUCCESS) 
         MessageBox (NULL, "Registry Not Closed", 
             _T("NDSShellExtension"), 
               MB_ICONERROR); 
        return cpRegKeyVal; 
       } 
      else 
      { 
        lCloseOut= RegCloseKey(hRegKey); 
        if (lCloseOut != ERROR_SUCCESS) 
        MessageBox (NULL, "Registry Not Closed", 
            _T("NDSShellExtension"), 
              MB_ICONERROR); 
        return ""; 
      } 
     } 
      return ""; 
} 
+1

Quel est le code de ReadFromRegistry? –

+0

Cela devrait fonctionner, donc c'est ailleurs - s'il vous plaît montrer le bloc de code réel. – egrunin

+0

@egrunin @Dark Falcon Mise à jour du code en question – Simsons

Répondre

5

Je crois que vous retournez un char * pointage à un tableau qui est alloué sur la pile, à savoir cette ligne:

TCHAR tSZValue[MAX_PATH] = {0}; 

suivi de:

char* cpRegKeyVal=tSZValue; 

Ceci est dangereux et vous expérimentez de première main le résultat final!

EDIT: pourquoi ne pas directement assigner à un CString dans la fonction et le retourner?

+0

+1 pour renvoyer directement un 'CString'. –

+0

@Mark B: Le retour d'un objet entraîne une copie inutile. Demander à l'appelant de transmettre un «char *» au stockage alloué à l'appelant. –

+2

@Robert, eh bien, vous pourriez passer un CString par référence? Sauvez-vous l'effort de traiter avec des tampons de caractères .. Je suppose que c'est une question de goût ... – Nim

5

La fonction renvoie un pointeur vers tSZValue qui est une variable locale, donc cesse d'exister quand il est hors de portée.

0

Vous renvoyez un pointeur sur tSZValue, qui est une variable temporaire et qui sera écrasée après la fin de la fonction.

La solution la plus simple: avoir ReadFromRegistry() retourner un CString au lieu d'un char *.

0

Il semble que ReadFromRegistry n'alloue pas de mémoire pour renvoyer la valeur (ou il le fait, mais il est sur la pile et est détruit avant le retour de la fonction). Au lieu de renvoyer un caractère *, vous pourriez peut-être passer une référence à un caractère * en tant que paramètre et allouer votre mémoire en dehors de ReadFromRegistry.