char* losing data - c++

I'm writing a C++ code with returns some data, the problem is: my const char is losing it value each time I call it from another file. I don't have idea what's happening.
My code on ProcClient.h
virtual void reportWorkflowError(unsigned int workflow,
const dp::String& errorCode) {
char message[1000];
snprintf(message, 1000, "Workflow: %s ERROR: %s", workflowToString(
workflow).utf8(), errorCode.utf8());
printf("[%s]", message);
errorInfo = message;
}
virtual const char * getErrorInfo() {
return errorInfo;
}
[Workflow: DW_FULFILL ERROR: E_ADEPT_NO_TOKEN]
[Workflow: ERROR: E_ADEPT_NOT_READY]
//two errors was thrown, and the errorInfo should has the last
On Services.cpp I start a "workflow", and if it throws an error the listener above is called, and after that I should get tha lastError pointer.
//g_drmClient is the ProcClient
bool RMServices::startFullfilment(dp::String acsm) {
//Do things
g_drmClient->getProcessor()->startWorkflows(dpdrm::DW_FULFILL);
size_t count = g_drmClient->getProcessor()->getFulfillmentItems();
printf("Number of items fulfilled: %d\n", count);
bool returnValue = !g_drmClient->hasError();
if (!returnValue)
lastError = g_drmClient->getErrorInfo());
printf("[%s]", lastError);
return returnValue;
}
Here it prints:
[\æ¾°Ô¯£ ¯|æ¾\æ¾er of items fulfer of ite]
What's happening?

char message[1000];
is a local variable residing on stack and goes out of scope on return of reportWorkflowError. So,
errorInfo = message; // errorInfo is simply pointing to garbage on method return.
Do some thing on these lines -
void className::foo()
{
char stackVariable[] = "abcdef" ;
classVariableCharPointer = new char[ sizeof(stackVariable) + 1 ] ;
strcpy( classVariableCharPointer, stackVariable ) ;
}
Also remember to deallocate the classVariableCharPointer in the destructor using delete[].

Yikes, you can't do that.
As soon as reportWorkflowError returns, all local variables are destroyed. This includes message, which returnValue points to.
A better approach would include making returnValue a character array, and calling srtrcpy() to copy the local data to the member variable. This way, the copy would still exist after message is destroyed.

You're putting message on the stack. Maybe you want it to be static, or better an instance variable.

Related

Replace to_utf8string to ensure proper string encoding on Windows 7 in a C++ DLL

I have a legacy C++ code that was written as a dll that can be called on Windows 10. A new requirement is to allow this dll to function properly on earlier Windows (7 Embedded, optionally XP as well). In short, the code is supposed to display body of a REST response.
The problem is, when called on Windows 7 without any modifications, there are additional (sometimes invisible) characters, especially at the beginning of the displayed output.
The code below is an abbreviated version and I believe to_utf8string is the root of the problem. What other function should I use in order for this dll to work on Windows 7 properly?
const char* foo(const char* param)
{
web::http::http_response resp = other_foo(param).get();
std::string utf8Response;
web::json::value json = resp.extract_json().get();
utf8Response = utility::conversions::to_utf8string(json.serialize());
return utf8Response.c_str();
}
Two example outputs on Windows 7:
Should be: {"statusCode": 400,
Should be: {"status":
The problem has nothing to do with character encoding, or OS used. The function is returning a dangling pointer to invalid memory!
The function is declaring a local std::string variable that goes out of scope when the function exits. It is returning a pointer to the std::string's internal character data, which is freed when the std::string is destroyed.
To solve this, the function will have to return a pointer to dynamically allocated memory that the caller can then free (or pass back to the DLL to free) at a later time when it is done using the data. For example:
const char* foo(const char* param)
{
web::http::http_response resp = other_foo(param).get();
web::json::value json = resp.extract_json().get();
std::string utf8Response = utility::conversions::to_utf8string(json.serialize());
// the caller can use CoTaskMemFree() to free this returned memory...
size_t size = utf8Response.size() + 1; // +1 for null terminator
char *ptr = static_cast<char*>(CoTaskMemAlloc(size));
if (ptr)
std::memcpy(ptr, utf8Response.c_str(), size);
return ptr;
}
const char* response = foo(param);
if (response) {
...
CoTaskMemFree(response);
}
Or:
const char* foo(const char* param)
{
web::http::http_response resp = other_foo(param).get();
web::json::value json = resp.extract_json().get();
std::string utf8Response = utility::conversions::to_utf8string(json.serialize());
// the caller must call free_foo_result() to free this memory...
size_t size = utf8Response.size() + 1; // +1 for null terminator
char *ptr = new(std::nothrow) char[size];
if (ptr)
std::memcpy(ptr, utf8Response.c_str(), size);
return ptr;
}
void free_foo_result(const char *data)
{
delete[] data;
}
const char* response = foo(param);
if (response) {
...
free_foo_result(response);
}
If re-writing the EXE to make these extra function calls is not an option, then the DLL will have to cache the JSON data so it can survive past the return, eg:
const char* foo(const char* param)
{
static thread_local std::string utf8Response;
web::http::http_response resp = other_foo(param).get();
web::json::value json = resp.extract_json().get();
utf8Response = utility::conversions::to_utf8string(json.serialize());
return utf8Response.c_str();
}

invalid pointer error when delete[] after c-string has been reallocated by function

I'm trying to delete[] a c-string (char*) previously allocated by another function using "new char[]". But I get an invalid pointer error.
First the code
class:
class myclass
{
public:
myclass(const char*);
~myclass();
char* getNum(const char*, myclass*);
private:
sqlite3* db; //db object
int rc; //int returned by sqlite3 functions
char* zErrMsg; //error message
char* sql; //sql statement
char* num; //<- this is it
static int callback(void*, int, char**, char**);
};
Some functions:
myclass::myclass(const char* filename)
{
//allocating
num = new char[2];
num[0] = 'i';
num[1] = '\0';
//connect to sqlite db using filename
}
char* myclass::getNum(const char* id, myclass* obj) //obj will be passed to callback function
{
std::cout<<"getNum"<<std::endl;
std::cout<<static_cast<void *>(&num[0])<<"("<<num[0]<<")"<<std::endl; //test1. writes address and first char. all seems ok
delete[] num; //here is the problem
num = new char[10];
strcpy(num, "not found");
std::cout<<static_cast<void *>(&num[0])<<"("<<num[0]<<")"<<std::endl; //test2. writes same address as test1 and first char. all seems ok
//sql query construction. Nothing wrong here.
//next query gets executed and callback function gets called.
rc = sqlite3_exec(db, query, callback, static_cast<void*>(obj), &zErrMsg);
return num; //returns num from db. "not found" otherwise
}
int myclass::callback(void* obj, int argc, char** argv, char** azColName)
{
std::cout<<"callback"<<std::endl;
myclass* const object = static_cast<myclass*>(obj);
std::cout<<static_cast<void *>(&object->num[0])<<"("<<object->num[0]<<")"<<std::endl; //test3. writes same address as test2 and first char. all seems ok
delete[] object->num; //no problems here
object->num = new char[strlen(argv[0])+1]; //address of num changes
object->num = argv[0];
std::cout<<static_cast<void *>(&object->num[0])<<"("<<object->num[0]<<")"<<std::endl; //test4. writes different address and first char. But all seems ok.
return 0;
}
about callback: seems like sqlite3_exec() wants a static callback function. So it can't see the "num" member of "myclass" since it's not static. And I cannot make it static because I need it for other member functions. So I'm passing the object address to in and using -> to access it's members.
Main:
int main(int argc, char const *argv[])
{
myclass a(filename);
a.getNum("id", &a) //works first time
a.getNum("id", &a) //doesn't work
return 0;
}
The first call of getNum() gets the job done. Nothing wrong.
The second one(after num has been modified by callback for the first time) I get an invalid pointer error.
It happens on the first delete[] inside the getNum function. If I try to output num right before it - everything works well and I get the correct output.
I understand that it has something to do with that reallocation inside the callback function, but I don't understand what. I have to dynamically reallocate it since I don't know the length of the value returned from db.
And I deallocate it in getNum because I don't want any memory leaks.
If I remove that deallocation (inside getNum) the program seems to work perfectly (but possible memory leak?).
I
In your callback, you reassign num to argv[0] from sqlite which is not allocated via new.
object->num = new char[strlen(argv[0])+1]; //address of num changes
object->num = argv[0]; // <--- here
You probably meant:
object->num = new char[strlen(argv[0])+1]; //address of num changes
strcpy (object->num, argv[0]);
object->num = argv[0];
You reassign your pointer here. Thus you try to delete argv[0].

Why const char* is not working with stringstream and read_json of boost?

I am trying to pass a character pointer to function which will read_json using the string internally. But after coming out of the function, the pointer's content is getting changed. Below is the code.
string tempstr;
void someFunc()
{
const char *ptr = getDiagnosticGroupValue("Device.ManagementServer");
printf("string : %s\n", getParameterValue(ptr, "URL"));
printf("string : %s\n", getParameterValue(ptr, "Username"));
}
const char* getParameterValue(const char *jsonstring, const char* param)
{
return getString(jsonstring, param);
}
const char* getString(const char *jsonstring, const char* param)
{
stringstream jsonstringstream;
jsonstringstream << jsonstring;
string paramstr(param);
try
{
boost::property_tree::ptree pt;
boost::property_tree::read_json(jsonstringstream, pt);
tempstr = pt.get<string>(paramstr);
return tempstr.c_str();
}
catch(...)
{
jsonstringstream.clear();
jsonstringstream.str("");
cout << "Node Doesn't exist" << endl;
return "N/A";
}
}
For the first node (URL), it is returning correct value and I am able to print the string in someFunc(). But ptr content is getting modified (and it is no longer json format string). So the second time, when getParameterValue() is called, read_json is throwing exception saying not json format. I was wondering why the ptr contents are getting changed even though I declared as const char* ptr. Can any one please let me know how to fix this issue.
I confirmed the problem is not with temporary object. I modified the code by creating global string and returning char * from global string. But I am facing the same problem. One more thing is when getParameterValue() is called first time, I put the print statement after read_json() to check the value of ptr, and ptr is already corrupted by that time.
getDiagnosticGrouapValue() is implementation is as below.
const char* getDiagnosticGroupValue(const char* group)
{
VZUAL& vzual = VZUAL::getInstance();
string groupStr(group, group + strlen(group));
return vzual.Diagnostics.getGroupValue(groupStr).c_str();
}
const string PlatformDiagnostics::getGroupValue(const string& _groupName_, const string& DUMMY)
{
boost::property_tree::ptree ptRead;
boost::property_tree::ptree ptWrite;
string path = _groupName_ + ".";
stringstream ss;
try {
boost::property_tree::read_json(Resource::diagnosticsFile.c_str(), ptRead);
}
catch (boost::property_tree::json_parser::json_parser_error &je) {
return Resource::defaultValue;
}
try {
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, ptRead.get_child(path))
ptWrite.put(v.first.data(), v.second.data());
}
catch (...) {
return Resource::defaultValue;
}
boost::property_tree::write_json(ss, ptWrite);
return ss.str();
}
You are returning pointer to string that is created on stack, inside getString function. This is undefined behaviour.
from your code, all the variables:
string paramstr(param);
boost::property_tree::ptree pt;
boost::property_tree::read_json(jsonstringstream, pt);
return (pt.get<string>(paramstr)).c_str();
indicate that this string is not created statically or globally.
If you are returning a pointer to some part of the jsonstring, ten maybe you should find this string inside jsonstring and return pointer to it. The problem is that it will not be null terminated (so you would need to return also lenght).
Other solution is to provide to getString a char array that will be returned from getString. But you must make sure its large enought, and incase it is too small then return NULL, so that the client code can provide larger buffer.

Safely reading string from Lua stack

How is it possible to safely read string value from Lua stack? The functions lua_tostring and lua_tolstring both can raise a Lua error (longjmp / exception of a strange type). Therefore the functions should be called in protected mode using lua_pcall probably. But I am not able to find a nice solution how to do that and get the string value from Lua stack to C++. Is it really needed to call lua_tolstring in protected mode using lua_pcall?
Actually using lua_pcall seems bad, because the string I want to read from Lua stack is an error message stored by lua_pcall.
Use lua_type before lua_tostring: If lua_type returns LUA_TSTRING, then you can safely call lua_tostring to get the string and no memory will be allocated.
lua_tostring only allocates memory when it needs to convert a number to a string.
Ok, When you call lua_pcall failed, it will return an error code. When you call lua_pcall successfully, you will get zero. So, first you should see the returned value by lua_pcall, then use the lua_type to get the type, at last, use the lua_to* functions the get the right value.
int iRet = lua_pcall(L, 0, 0, 0);
if (iRet)
{
const char *pErrorMsg = lua_tostring(L, -1); // error message
cout<<pErrorMsg<<endl;
lua_close(L);
return 0;
}
int iType = lua_type(L, -1);
switch (iType)
{
//...
case LUA_TSTRING:
{
const char *pValue = lua_tostring(L, -1);
// ...
}
}
It's all.
Good luck.
You can use the lua_isstring function to check if the value can be converted to a string without an error.
Here's how it's done in OpenTibia servers:
std::string LuaState::popString()
{
size_t len;
const char* cstr = lua_tolstring(state, -1, &len);
std::string str(cstr, len);
pop();
return str;
}
Source: https://github.com/opentibia/server/blob/master/src/lua_manager.cpp

const char* in my class has junk character(s) after it's returned from function

Class:
class myclass {
public:
myclass(void);
const char* server;
private:
char pidchar[6];
int pidnum;
};
The function
myclass parseINI(const char* file)
{
myclass iniOptions;
CSimpleIniA ini;
ini.SetUnicode();
ini.LoadFile(file);
const char* server = ini.GetValue("", "server", "");
iniOptions.server = server;
std::cout << server << "\n"; // Prints the correct value here
fflush(stdout);
return iniOptions;
}
Calling it from the main function
int _tmain(int argc, TCHAR* argv[])
{
myclass options;
options = parseINI("myapp.ini");
std::cout << options.server << "\n"; // It prints junk here
return 0;
}
What did I do wrong?
The const char* returned by GetValue() probably belonged to the ini object. When you exited the parseIni() function, ini went out of scope and was destroyed, which could mean your pointer is no longer valid.
Try using a std::string for the server member type instead of const char*.
It looks like you are using memory that is released when CSimpleIniA goes out of scope in parseINI.
const char* server = ini.GetValue("", "server", "");
iniOptions.server = server;
Copy the value that is returned into a new memory block before you return from the parseINI function.
string server = ini.GetValue("", "server", "");
iniOptions.server = new char[server.length() + 1];
std::copy(server.begin(), server.end(), iniOptions.server);
iniOptions.server[server.length()] = 0;
const char* server = ini.GetValue("", "server", "");
This value is falling out of scope when the function terminates, so when you assign the value of that pointer to your object's server pointer, the place in memory they point to is having its memory freed off the stack at the end of the function, and it's then overtaken by other things.
Using a std::string or even just a char[] will be preferred to just fix the problem with the least amount of changes, as they will by assigned the actual value and not a location in memory like pointers.
What you really should do is look up referential transparency, though. That will prevent problems like this from occurring ever again
I's guess that the lifetime of the data pointed to by the char* returned from CSimpleIniA::GetValue() is the same as the CSimpleIni object itself. So when ini is destructed, the pointer returned from GetValue() becomes invalid. (I've never used CSimpleIni, and haven't looked at the docs carefully enough to know for sure, but that's what the behavior points to).
I'd suggest changing myclass::server to be a std:string object and set it using something like:
iniOptions.server = std::string(server);
which will give the myclass::server object it's own copy of the string data.
The way you are using class as a function returned data type in C++ is totally wrong.
In C++ there are 2 kinds of data type: value type, reference type.
class belongs to second one; From a function you can return a value type data or a pointer of any data.But you cann't retun a entity of a reference type. Because a entity of a reference type will be released right after the code reached out of the scope which the entity is defined.
You can do in either way:
1:
define parseINI as:
myclass* parseINI(const char* file)
{
myclass* iniOptions = new myclass();
........
return iniOptions;
}
and then use it like this:
myclass* options = parseINI("myapp.ini");
2:
define parseINI as:
void parseINI(myclass& options, const char* file)
{
........//asigne value to options's members
}
and then use it like this:
myclass options;
parseINI(options,"myapp.ini");
3:
Do what you did, but add a asignment method (operator=) to myclass
The problem is that the local variable server points to a character buffer returned by ini.GetValue(), which is destroyed when paraseINI() returns.
One way to fix this is to allocate a new buffer yourself and copy the characters.
const char* server = ini.GetValue("", "server", "");
int length = strlen(server) + 1; // length of the string +1 for the NULL character.
delete [] iniOptions.server; // free the old buffer
iniOptions.server = new char[length]; // allocate your own buffer
strncpy(iniOptions.server, server, length); // copy the characters
For this to work you have to make myclass::server non-const, and you have to initialize it to NULL in the constructor and delete it in the destructor.
A better way to deal with this situation would be use std::string instead of char * for muclass::server. This way std::string would take care of memory management for you, and the code would be exception-safe.
If you make muclass::server an std::string, then you simply do
const char* server = ini.GetValue("", "server", "");
iniOptions.server = std::string(server);
And you do not have to do anything with it in the constructor or the destructor.
iniOptions is located on the stack and disposed automatically when the function returns. You should allocate it on heap using new()