Print out pointer value - c++

I am doing a threading, but i don't know how to print out the pointer value.
UINT __cdecl CThreadDlg::func(LPVOID pParam)
{
data *ptr = (data*)pParam;
AfxMessageBox(L"You have entered a thread function.");
ptr->a = "abc12345"; // char * a
AfxMessageBox(???); // what should i put here to print out the value of a?
return 0;
}

Maybe something like this:
CString a;
a.Format(_T("%p"), ptr->a);
AfxMessageBox(a);
Edit:
to get value 'ptr->a' points to:
a.Format(_T("%s), ptr->a);

I believe
ptr->a
But that completely depends on the AfxMessageBox API.
Edit: Looks like AfxMessageBox expects a LPCTSTR which is nothing but a const char *.
LPCTSTR lpStr = (LPCTSTR)ptr->a;
This should help if your compiler isn't casting automatically

Use the swprintf function to build a C string with the text, then print that. Consider this example:
UINT __cdecl CThreadDlg::func(LPVOID pParam)
{
data *ptr = (data*)pParam;
AfxMessageBox(L"You have entered a thread function.");
ptr->a = "abc12345"; // char * a
wchar_t buf[ 1024 ];
swprintf( buf, "ptr->a points to %p", ptr->a );
AfxMessageBox(buf);
return 0;
}

Related

What wrong I have done? The function of GetDiskFreeSpaceExA didn't work at all

I tried to use GetDiskFreeSpaceExA function, but it doesn't work:
int drvNbr = PathGetDriveNumber(db7zfolderw);
if (drvNbr == -1) // fn returns -1 on error
{
const char * errmsg = "error occured during get drive number";
strcpy_s(retmsg, strlen(errmsg) + 1, errmsg);
return -3;
}
char driverletter = (char)(65 + drvNbr);
string driverstr(1, driverletter);
driverstr = driverstr + ":";
PULARGE_INTEGER freespace = 0;
PULARGE_INTEGER totalnumbtype = 0;
PULARGE_INTEGER totalnumberfreebyte = 0;
fileSize = SzArEx_GetFileSize(&db, i);
BOOL myresult=GetDiskFreeSpaceExA(
driverstr.c_str(),
freespace,
totalnumbtype,
totalnumberfreebyte
);
The value of variable freespace is 0. I have no idea why it didn't work if the value of variable which is driverstr.c_str() was D:?
Thanks for your help.
You need to supply pointers to variables that will hold the value returned. Right now you a re supplying null pointers so nothing is retured:
::ULARGE_INTEGER freespace{};
::ULARGE_INTEGER totalnumbtype{};
::ULARGE_INTEGER totalnumberfreebyte{};
::BOOL myresult
{
::GetDiskFreeSpaceExA
(
driverstr.c_str()
, &freespace
, &totalnumbtype
, &totalnumberfreebyte
)
};
It would also be a good idea to use wide char versions of these functions.

(C++) Variable value changing when I call a function

I have the following code
NCore.h
#ifndef _NCORE_H_
#define _NCORE_H_
#include <Windows.h>
#include <cstdio>
namespace Neat
{
class NCore
{
private:
// Structure Definitions
struct NApplicationVersion
{
int major = 0;
int minor = 0;
int build = 0;
LPCSTR toString();
};
// Application Variables
LPCSTR applicationName;
NApplicationVersion applicationVersion;
protected:
public:
NCore();
LPCSTR ApplicationName(LPCSTR _applicationName = NULL);
NApplicationVersion ApplicationVersion(LPCSTR _applicationVersion = NULL);
};
}
#endif
NCore.cpp
#include "NCore.h"
Neat::NCore::NCore()
{
this->applicationName = NULL;
}
LPCSTR Neat::NCore::NApplicationVersion::toString()
{
char str[16];
memset(&str, 0, sizeof(str));
sprintf_s(str, sizeof(str), "%i.%i.%i", this->major, this->minor, this->build);
return str;
}
LPCSTR Neat::NCore::ApplicationName(LPCSTR _applicationName)
{
if (_applicationName)
this->applicationName = _applicationName;
return this->applicationName;
}
Neat::NCore::NApplicationVersion Neat::NCore::ApplicationVersion(LPCSTR _applicationVersion)
{
if (_applicationVersion)
{
//I know this isn't needed. I was just testing something.
Neat::NCore::NApplicationVersion *nav = (Neat::NCore::NApplicationVersion *)malloc(sizeof(Neat::NCore::NApplicationVersion));
sscanf_s(_applicationVersion, "%i.%i.%i", &nav->major, &nav->minor, &nav->build);
this->applicationVersion.major = nav->major;
this->applicationVersion.minor = nav->minor;
this->applicationVersion.build = nav->build;
free(nav);
}
return this->applicationVersion;
}
main.cpp
#include <Windows.h>
#include "NCore.h"
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT iCmdShow)
{
Neat::NCore n;
n.ApplicationName("test");
LPCSTR test = n.ApplicationName();
LPCSTR test2 = n.ApplicationVersion().toString();
if (strcmp(test2, "0.0.0") == 0)
{
MessageBox(NULL, "", "", MB_OK);
}
n.ApplicationVersion("10.50.136");
if (strcmp(test2, "0.0.0") == 0)
{
MessageBox(NULL, "", "", MB_OK);
}
LPCSTR test3 = n.ApplicationVersion().toString();
if (test3 == "10.50.136")
{
MessageBox(NULL, "", "", MB_OK);
}
while (true);
return 0;
}
My issue is that test2 initializes as "0.0.0" and the first MessageBox is shown. But after I call ApplicationVersion("10.50.136") it changes test2 to "10.50.136" and the second MessageBox is not shown.
Can someone please explain why this happens/how to fix it?
EDIT: I was testing a function that could operate as both a get/set function. I'm fairly new to this and I learn by failing. I just can't figure out what exactly went wrong here.
EDIT 2: I changed the code as follows...
NCore.h
struct NApplicationVersion
{
int major = 0;
int minor = 0;
int build = 0;
char asString[16];
LPCSTR toString();
};
NCore.cpp
LPCSTR Neat::NCore::NApplicationVersion::toString()
{
memset(this->asString, 0, 15);
sprintf_s(this->asString, 16, "%i.%i.%i", this->major, this->minor, this->build);
return this->asString;
}
Is this viable?
From my understanding, I was putting the variable "str" on the stack. This causes it to not have a set place in memory(?) and when other calls altered the stack they also altered the data the pointer "test2" was trying to read from?
It's pretty easy, actually. toString invokes undefined behavior by returning an array (str) that's allocated locally to the function and goes out of scope with the return:
LPCSTR Neat::NCore::NApplicationVersion::toString()
{
char str[16];
memset(&str, 0, sizeof(str));
sprintf_s(str, sizeof(str), "%i.%i.%i", this->major, this->minor, this->build);
return str;
}
In most common C++ implementations, str will be on the stack. (The C++ standard does not require a unified concept of "stack" where all automatic variables live, but most common implementations work that way.)
So, subsequent functions that modify the stack will also modify the C-style string pointed to by the call to toString(). The subsequent call to n.ApplicationVersion(), for example, would likely trash str. Your second message box won't show as long as the string changed to anything other than "0.0.0", and it won't take much to corrupt the stack in that way.
Based on your subsequent edit: Making the string a member of your class will somewhat work. Any call to toString will rewrite this string, affecting all callers that saved a pointer to this buffer.
Still, this is certainly much safer than saving the string on the stack. Furthermore, as long as only toString writes to this buffer, you have well defined rules for when that string is valid.
LPCSTR is not the string, it is just the pointer to the char array. When you set new version, the char array itself is changing. That's why you observer the change in test2 variable immediately. If you want this string not to be changed, copy and save it in your internal buffer.

Using string pointers in C++ and Objective-C

I have a sample project here on github where I created a c++ wrapper class for an external C++ library that I want to use in Objective-C.
I don't understand why my returned pointers are sometimes correct and sometimes wrong. Here's sample output:
Test Data = 43343008
In Compress 43343008
Returned Value = 43343008
Casted Value = 43343008
Test Data = 2239023
In Compress 2239023
Returned Value = 2239023
Casted Value = 2239023
Test Data = 29459973
In Compress 29459973
Returned Value = 29459973
Casted Value = l.remote
Test Data = 64019670
In Compress 64019670
Returned Value =
Casted Value = stem.syslog.master
In the above output you can see that the 1st and 2nd click of the button outputs the results I was expecting. In each of the other clicks either the returned value or casted value are invalid. I'm assuming this is because my pointer is pointing to an address I wasn't expecting. when running the app multiple times, any button click could be right or wrong.
I also tried with a single thread but experienced similar results.
The complete code is on github but here are the important bits.
ViewController.m
#import "ViewController.h"
extern const char * CompressCodeData(const char * strToCompress);
#implementation ViewController
...
// IBAction on the button
- (IBAction)testNow:(id)sender
{
[self performSelectorInBackground:#selector(analyze) withObject:nil];
}
- (void)analyze
{
#synchronized(self) {
const char *testData = [[NSString stringWithFormat:#"%d",
(int)(arc4random() % 100000000)] UTF8String];
NSLog(#"Test Data = %s", testData);
const char *compressed = CompressCodeData(testData);
NSLog(#"Returned Value = %s", compressed);
NSString *casted = [NSString stringWithCString:compressed
encoding:NSASCIIStringEncoding];
NSLog(#"Casted Value = %#\n\n", casted);
}
}
#end
SampleWrapper.cpp
#include <iostream>
#include <string.h>
#include <CoreFoundation/CoreFoundation.h>
using namespace std;
extern "C"
{
extern void NSLog(CFStringRef format, ...);
/**
* This function simply wraps a library function so that
* it can be used in objective-c.
*/
const char * CompressCodeData(const char * strToCompress)
{
const string s(strToCompress);
// Omitted call to static method in c++ library
// to simplify this test case.
//const char *result = SomeStaticLibraryFunction(s);
const char *result = s.c_str();
NSLog(CFSTR("In Compress %s"), result);
return result;
}
}
You are returning a pointer to at object that has been deallocated.
const string s(strToCompress);
…
const char *result = s.c_str();
NSLog(CFSTR("In Compress %s"), result);
return result;
s does not exist after CompressCodeData() function is over, so the pointer to it's internal memory is invalid.
You could allocate a chunk of memory to hold the response, but it would be up to the caller to release it.
char *compressed = CompressCodeData(testData);
NSLog(#"Returned Value = %s", compressed);
NSString *casted = [NSString stringWithCString:compressed
encoding:NSASCIIStringEncoding];
free(compressed);
NSLog(#"Casted Value = %#\n\n", casted);
…
const char * CompressCodeData(const char * strToCompress)
…
char *result = strdup(s.c_str());
Another solution is to pass in the memory to store the data into.
char compressed[2048]; // Or whatever!
CompressCodeData(testData, compressed, sizeof(compressed));
NSLog(#"Returned Value = %s", compressed);
NSString *casted = [NSString stringWithCString:compressed
encoding:NSASCIIStringEncoding];
NSLog(#"Casted Value = %#\n\n", casted);
…
void CompressCodeData(const char * strToCompress, char *result, size_t size)
…
s.copy(result, size - 1);
result[s.length() < size ? s.length() : size-1] = '\0';

How to pass TCHAR* returned by one function to another function in(Managed) C++

I have a function called ReversedIPAddressString which takes IPAddress as a TCHAR* and then returns reveresed IPAddress as TCHAR*. I am able to get reversed IP fine but when I passed this TCHAR* pointer(reversedIP) to some other function(let's say dns.query(TCHAR*)),IP value always junk. I am wondering what I am missing?
I am pasting my code here for your reference...
Caller Method:
bool DNSService::DoesPtrRecordExixts(System::String^ ipAddress)
{
IntPtr ipAddressPtr = Marshal::StringToHGlobalAuto(ipAddress);
TCHAR* ipAddressString = (TCHAR*)ipAddressPtr.ToPointer();
bool bRecordExists = 0;
WSAInitializer initializer;
Locale locale;
// Initialize the identity object with the provided credentials
SecurityAuthIdentity identity(userString,passwordString,domainString);
// Initialize the context
DnsContext context;
// Setup the identity object
context.acquire(identity);
DnsRecordQueryT<DNS_PTR_DATA> dns(DNS_TYPE_PTR, serverString);
try
{
bRecordExists = dns.query(ReversedIPAddressString(ipAddressString)) > 0;
}
catch(SOL::Exception& ex)
{
// Free up the pointers to the resources given to this method
Marshal::FreeHGlobal(ipAddressPtr);
if(ex.getErrorCode() == DNS_ERROR_RCODE_NAME_ERROR)
return bRecordExists;
else
throw SOL::Exception(ex.getErrorMessage());
}
// Free up the pointers to the resources given to this method
Marshal::FreeHGlobal(ipAddressPtr);
return bRecordExists;
}
Called Method:
TCHAR* DNSService::ReversedIPAddressString(TCHAR* ipAddressString)
{
TCHAR* sep = _T(".");
TCHAR ipArray[4][4];
TCHAR reversedIP[30];
int i = 0;
TCHAR* token = strtok(ipAddressString, sep);
while(token != NULL)
{
_stprintf(ipArray[i], _T("%s"), token);
token = strtok((TCHAR*)NULL, sep);
i++;
}
_stprintf(reversedIP, _T("%s.%s.%s.%s.%s"), ipArray[3], ipArray[2], ipArray[1], ipArray[0],_T("IN-ADDR.ARPA"));
return reversedIP;
}
DNS.Query method declaration:
int query(__in const TCHAR* hostDomain, __in DWORD options=DNS_QUERY_STANDARD)
Hope to get help from you.
Thanks in advance!
Ramani
You're returning a pointer to the local array TCHAR reversedIP[30]; which is allocated withing your function ReversedIPAddressString. When this function exits, your array becomes out of scope - it does not exist anymore. This is undefined behaviour.
You should return a string object instead, for example std::basic_string<TCHAR>
See this question: pointer-to-local-variable

char* value gets corrupted during assignment

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 "";
}
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?
The function returns a pointer to tSZValue which is a local variable, so ceases to exist when it goes out of scope.
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 *.
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.