views:

79

answers:

4

I have the following code , which gets a return value from a function as char*

cDestDrive = ReadFromRegistry(HKEY_CURRENT_USER,NDSPATH,szDestPathRoot);

I am able to read the value inside cDestDrive till the time I am assigning it. The moment I am assigning it:

 CString strServerAddress = cDestDrive;

the value of cDestDrive gets changed (corrupted) and I am not able to get the value in CString strServerAddres any Idea why this is happening.

Edit: Code to Read from Registry

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 "";
}
+4  A: 

The function returns a pointer to tSZValue which is a local variable, so ceases to exist when it goes out of scope.

Clifford
+3  A: 

I believe you are returning a char* pointing to a an array that is allocated on the stack, i.e. this line:

TCHAR tSZValue[MAX_PATH] = {0};

followed by:

char* cpRegKeyVal=tSZValue;

This is dangerous, and you are experiencing first hand the end result!

EDIT: why don't you directly assign to a CString in the function and return that?

Nim
+1 for directly returning a `CString` .
Mark B
@Mark B: Returning an object results in unnecessary copying. Have the caller pass a `char*` to caller allocated storage.
Robert S. Barnes
@Robert, well, you could pass in a CString by reference? Save your self the effort of dealing with buffers of characters.. I guess it's a matter of taste...
Nim
@Robert: premature optimization. You don't know that 1) the extra copying is going to make a measurable difference to overall performance, and 2) that the copying *will actually happen*. Mainstream compilers implement RVO and NRVO to avoid it, so I see little reason to mutiliate your code's readability to avoid a performance hit that neither matters nor actually *exists*.
jalf
A: 

You are returning a pointer to tSZValue, which is a temp variable and will be overwritten sometime after the function exits.

The simplest solution: have ReadFromRegistry() return a CString instead of a char *.

egrunin
A: 

It looks like ReadFromRegistry doesn't allocate memory to return the value (or it does, but it's on the stack and is destroyed before the function returns).

Instead of returning a char *, maybe you could pass in a reference to a char * as a parameter, and allocate your memory outside of ReadFromRegistry.

Dakota Hawkins