Can I use a static var to "cache" the result? C++ - c++

I am using a function that returns a char*, and right now I am getting the compiler warning "returning address of local variable or temporary", so I guess I will have to use a static var for the return, my question is can I make something like if(var already set) return var else do function and return var?
This is my function:
char * GetUID()
{
TCHAR buf[20];
StringCchPrintf(buf, 20*sizeof(char), TEXT("%s"),
someFunction());
return buf;
}
And this is what I want to do:
char * GetUID()
{
static TCHAR buf[20];
if(strlen(buf)!=0) return buf;
StringCchPrintf(buf, 20*sizeof(char), TEXT("%s"),
someFunction());
return buf;
}
Is this a well use of static vars? And should I use ZeroMemory(&buf, 20*sizeof(char))? I removed it because if I use it above the if(strlen...) my TCHAR length is never 0, should I use it below?

The reason you're getting a warning is because the memory allocated within your function for buf is going to be popped off the stack once the function exits. If you return a pointer to that memory address, you have a pointer to undefined memory. It may work, it may not - it's not safe regardless.
Typically the pattern in C/C++ is to allocate a block of memory and pass a pointer to that block into your function. e.g.
void GetUID( char* buf )
{
if(strlen(buf)!=0) return;
StringCchPrintf(buf, 20*sizeof(char), TEXT("%s"), someFunction());
}
If you want the function (GetUID) itself to handle caching the result, then you can use a static, a singleton (OOP), or consider thread local storage.
(e.g. in Visual C++)
__declspec(thread) TCHAR buf[20];

It's OK if your code is single threaded. The buffer will be set to contain all zeros when the function is entered for the very first time, so there is no need to explicitly set its contents to zero. But these days all code eventually tends to become multi-threaded, so I would not do this, if I were you.

What you should do instead is allocate buf dynamically using new, and then return it. But be aware that the caller would be responsible for deallocating the memory.
Better yet, use std::string instead of char *.

You could do that, but it won't be thread-safe. You should also be careful with what you do with the result, since you can not store it between subsequent calls to the function (without copying it, of course).
You should also initialize the static variable to the empty string.

This is how I would do it.
It caches; it does not rely on the buffer being 0.
It does have the implicit assumption that 'buf' will be identical from thread to thread, which is not (to my knowledge) correct. I would use a global for that purpose.
//returns a newly allocated buffer, every time. remember to delete [] it.
char * GetUID()
{
static TCHAR buf[20];
static bool run = false;
TCHAR ret_mem = new TCHAR[20];
if(run)
{ return ret_mem; }
//do stuff to the buf
//assuming - dst, src, size.
memcpy(ret_mem, buf, 20);
run = true;
return ret_mem;
}

Related

Using String c_str() to return char*

I am working on some legacy code where I have to make some changes in the cpp file.The cpp file contains entire code in extern "c" block -
I updated a function that returns a char* .The code looks something like func1() below.
Since I use std::strring and stringstream I included the sstream and string header files before extern block.
The below function is called from both c and cpp files.So I cannot return std::string here -
char* func1(someStruct* pt){
std::strig nam = somefunc(pt);
//have to append some integer in particular format
std::stringstream ss;
ss<<nam<<pt->int1 ......;
nam = ss.str();
//More code here for returning char* based on queries - (a)
}
At one of the places where this function is called -
void otherFunc(.....){
//......
char* x = func(myptr);
if(based_on_some_condition){
char* temp = func3(x); //returns a char* to dynamically allocated array.
strcpy(x,temp); //copying (b)
}
//..........
}
Following is my query -
1) At (a) I can return char* in following 2 forms.I have to make a decision such that copying at (b) does not cause any undefined behavior -
i)Create a char array dynamically with size = nam.length()+10 (extra 10 for some work happening in func3).<br>
char* rtvalue = (char*)calloc(sizeof(char),nam.length()+10);
strcpy(rtvalue,nam.c_str());
return rtvalue;
And free(temp); in otherFunc() after strcpy(x,temp);
ii) Declare 'nam' as static std::string nam;
and simply return const_cast<char*>(nam.c_str());
Will defining 'nam' with static scope ensure that a correct return happen from function (ie no dangling pointer at 'x')?
More importantly, can I do this without worrying about modification happening at (b).
Which one is a better solution?
Problem is returning a char *. When you using C++ you should not use this type. This is not C! std::string or std::vector<char> should be used.
If you will use char * as return type in this kind of function it will end with undefined behavior (access to released memory) or memory leak.
If you will use static std::string nam; function will maintain internal state and this is always leads to trouble.
For example if you create threading functionality you will have undefined behavior. Even worse if you will use this function twice for some reason result of second call will have impact on result for first call (for example your coworker will use this function since he will not expect hiden side effects).
If you are designing some API which should be accessible from C code than you should design this API in different way. I do not know what kind of functionality you are providing by most probably you should something like this:
char *func1(someStruct* pt, char *result, int size){ // good name could be like this: appendStructDescription
std::strig nam = somefunc(pt);
//have to append some integer in particular format
std::stringstream ss;
ss<<nam<<pt->int1 ......;
nam = ss.str();
int resultSize = std::min(size - 1, nam.length());
memcpy(result, nam.c_str(), resultSize);
result[resultSize] = 0;
return result + resultSize;
}
This approach has big advantages: responsibility for a memory management goes to caller, user of the API understands what is expected.
It is true that you should return string, but if you absolutely need to return char*, first method is better. And don't forget free. Otherwise, expressions like strcmp(f(pt1), f(pt2)) would return unpredictable results.

Use a string as a char

I have been given this definitions, the function should return what is in info->phrase. However info->phrase can contain a string in which case I can only make it return the first char on info->phrase. Is there a way to make a string compatible with the char type? I am new to c++.
struct rep_info {
int num;
char *phrase;
};
I´ve tried few thing but get type errors, this was my latest attempt
char *phrase_info(rep_info info) {
char text[std::strlen(info->phrase) + 1];
text = info->phrase;
return text;
}
Since you said you have been given these definitions, let's fix the problem with the current setup first. Looking at your function, you are trying to copy into this local array (incorrectly I might add), and return this local variable. There are a number of things wrong with this, including the syntax and the fact that the local variable is destroyed when the function exits.
If you just need to get the value of the phrase member variable, the simplest solution would be to just access the member variable directly and return it:
char *phrase_info(rep_info info) {
return info.phrase; //since info is not a pointer, use the '.' accessor
}
If you mean to pass a pointer to the function, you would re-write it like this:
char *phrase_info(rep_info *info) {
return info->phrase;
}
But it seems like you feel the need to copy the contents of info->phrase into a new memory space? If so, then you would do something like this where you first allocate new memory and return this buffer:
char *phrase_info(rep_info *info) {
char *buf = new char[std::strlen(info->phrase) + 1];
std::strcpy(buf,info->phrase); //copies info->phrase into buf
return buf;
}
You would then need to use delete on the returned memory value to clean up the memory allocated by new, otherwise you will have a memory leak.
Overall, all the above solution would potentially solve the problem given some parameters you haven't made clear. To round this out, this should be written more like:
class rep_info {
private:
int num;
std::string phrase;
public:
rep_info(int n, std::string p) : num(n), phrase(p) {}
std::string get_phrase() { return phrase; }
// other functions
};
//later in the code
rep_info info(...);
info.get_phrase();
Ideally, you would wrap these member variables into their own object with corresponding member functions that can get and set these values. Moreover, for handling strings in C++, std::string is the preferred option for storing, copying, modifying, etc. strings over the older char * C-style string.

How to make this code less memory leak prone?

As an introduction, note that I am a Java programmer still getting used to the memory management issues in C++.
We have a base class which is used to encoded objects to a string of ASCII characters. Essentially, the class is using a stringstream class member to convert different datatypes to one long string, and then returns a char* to the caller which contains the encoded object data.
In testing for memory leaks, I am seeing that the implementation we are using seems prone to create memory leaks, because the user has to always remember to delete the return value of the method. Below is an excerpt of the relevant parts of the code:
char* Msg::encode()
{
// clear any data from the stringstream
clear();
if (!onEncode()) {
return 0;
}
// need to convert stringstream to char*
string encoded = data.str();
// need to copy the stringstream to a new char* because
// stringstream.str() goes out of scope when method ends
char* encoded_copy = copy(encoded);
return encoded_copy;
}
bool Msg::onEncode(void)
{
encodeNameValue(TAG(MsgTags::TAG_USERID), companyName);
encodeNameValue(TAG(MsgTags::TAG_DATE), date);
return true;
}
bool EZXMsg::encodeNameValue(string& name, int value)
{
if(empty(value))
{
return true;
}
// data is stringstream object
data << name << TAG_VALUE_SEPARATOR << value << TAG_VALUE_PAIRS_DELIMITER;
return true;
}
char* copy(string& source) {
char *a=new char[source.length() +1];
a[source.length()]=0;
memcpy(a,source.c_str(),source.length());
return a;
}
UPDATE
Well - I should have been more accurate about how the result of encode() is consumed. It is passed to boost:async_write, and program is crashing because I believe the string goes out of scope before async_write complete. It seems like I need to copy the returned string to a class member which is alive for life time of the class which sends the message (?).
This is the way the encode() method is actually used (after I changed the return value of to string):
void iserver_client::send(ezx::iserver::EZXMsg& msg) {
string encoded = msg.encode();
size_t bytes = encoded.length();
boost::asio::async_write(socket_, boost::asio::buffer(encoded, bytes), boost::bind(&iserver_client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
It looks like the proper way to do this is to maintain a queue/list/vector of the strings to async write. As noted here (and also in the boost chat_client sample). (But that is a separate issue.)
For this question:
in your copy function you return a pointer to a heap memory!So user maybe create memory leak,I think you can not use this copy function,you can do just like this in your encode func:
return data.str();
If you want to get a char*, you can use the member function of string:c_str(),
just like this:
string ss("hello world");
const char *p = ss.c_str();
If you use a stack string object you will not create memory leak,
You could just return a std::string. You have one there anyway:
string Msg::encode()
{
// clear any data from the stringstream
clear();
if (!onEncode()) {
return string{};
}
return data.str();
}
Then the caller would look like:
Msg msg;
msg.userID = 1234;
send(msg.encode().c_str());
The only way of achieving "automatic" deletion is with a stack variable (at some level) going out of scope. In fact, this is in general the only way of guaranteeing deletion even in case of an exception, for example.
As others mentioned std::string works just fine, since the char * is owned by the stack-allocated string, which will delete the char *.
This will not work in general, for example with non char * types.
RAII (Resource Acquisition is Initialization) is a useful idiom for dealing with such issues as memory management, lock acquisition/release, etc.
A good solution would be to use Boost's scoped_array as follows:
{
Msg msg;
msg.userID = 1234;
scoped_array<char> encoded(msg.encode());
send(encoded.get());
// delete[] automatically called on char *
}
scoped_ptr works similarly for non-array types.
FYI: You should have used delete[] encoded to match new char[source.length() +1]
While using a std::string works adequately for your specific problem, the general solution is to return a std::unique_ptr instead of a raw pointer.
std::unique_ptr<char[]> Msg::encode() {
:
return std::unique_ptr<char[]>(encoded_copy);
}
The user will then get a new unique_ptr when they call it:
auto encoded = msg.encode();
send(encoded.get());
and the memory will be freed automatically when encoded goes out of scope and is destroyed.

Temporary function arguments that last during scope containing function call

Consider a typical function that fills in a buffer:
const char* fillMyBuffer( const char* buf, int size );
Suppose this function fills the buffer with some useful data, that I want to use almost immediately after the call, and then I want to get rid of the buffer.
An efficient way of doing this is to allocate on the stack:
doStuff();
{
char myBuf[BUF_LEN];
const char* pBuf = fillMyBuffer( myBuf, BUF_LEN );
processBuffer( pBuf );
}
doOtherStuff();
So this is great for my library because the buffer is allocated on the stack - being essentially no cost to allocate, use and discard. It lasts the entire scope of the containing braces.
But I have a library where I do this pattern all the time. I'd like to automate this a little. Ideally I'd like code that looks like this:
doStuff();
{
// tricky - the returned buffer lasts the entire scope of the braces.
const char* pBuf = fillMyBufferLocal();
processBuffer( pBuf );
}
doOtherStuff();
But how to achieve this?
I did the following, which seems to work, but I know is counter to the standard:
class localBuf
{
public:
operator char* () { return &mBuf[0]; }
char mBuf[BUF_LEN];
};
#define fillMyBufferLocal() fillMyBuffer( localBuf(), BUF_LEN );
As a practical matter, the buffer is lasting on the stack during the entire lifetime of the containing braces. But the standard says that the object only has to last until the function returns. E.g. technically its just as unsafe as if I'd allocated the buffer on the stack inside the function.
Is there a safe way to achieve this?
I would generally recommend your original solution. It separates the allocation of the buffer from filling it. However, if you want to implement this fillMyBufferLocal alternative, it will have to dynamically allocate the buffer and return a pointer to it. Of course, if you return a raw pointer to dynamically allocated memory, it's very unclear that the memory should later be destroyed. Instead, return a smart pointer that encapsulates the appropriate ownership:
std::unique_ptr<char[]> fillMyBufferLocal()
{
std::unique_ptr<char[]> buffer(new char[BUF_LEN]);
// Fill it
return buffer;
}
Then you can use it like so:
auto buffer = fillMyBufferLocal();
processBuffer(buffer.get());
I do not think you should want to do this. It just makes the code harder to understand.
Automatic storage duration means that when an object goes out of scope, it is destroyed. Here you want trick the system into something that behaves like creating an object with automatic storage duration (i.e. allocates on the stack), but without respecting the corresponding rules (i.e. without being destroyed when returning from fillMyBuffer()).
The closest, meaningful thing you can do in my opinion is to use a global buffer that fillMyBuffer() can reuse, or let that buffer be a static variable inside fillMyBuffer(). For instance:
template<int BUF_LEN = 255>
const char* fill_my_buffer()
{
static char myBuf[BUF_LEN];
// Fill...
return myBuf;
}
However, I strongly suggest reconsidering your requirements, and either:
Keep using the solution you are currently adopting (i.e. transparently allocate on the stack); or
Allocate the buffer dynamically inside fillMyBuffer() and return a RAII wrapper (like a unique_ptr) to this dynamically allocated buffer.
UPDATE:
As a last, desperate attempt, you could define a macro that does the allocation and the invocation of fill_my_buffer() for you:
#define PREPARE_BUFFER(B, S) \
char buffer[S]; \
const char* B = fill_my_buffer(buffer, S);
You would then use it this way:
PREPARE_BUFFER(pBuf, 256);
processBuffer(pBuf);
You could write a class that contains a stack-based buffer and converts to char const *, e.g.
void processBuffer(char const * buffer);
char const * fillMyBuffer(char const * buffer, int size);
int const BUF_LEN = 123;
class Wrapper
{
public:
Wrapper(char const * (*fill)(char const *, int))
{
fill(&m_buffer[0], m_buffer.size());
}
operator char const * () const { return &m_buffer[0]; }
private:
std::array<char, BUF_LEN> m_buffer;
};
void foo()
{
Wrapper wrapper(fillMyBuffer);
processBuffer(wrapper);
}

Pass char[N] param to thread

i have a variable declared as
char myvariable[N] = "blablabla"
and i need to pass it to a thread
DWORD MyThread(LPVOID lpdwParam)
i tried to cast inside the thread function the lpdwParam in char* but it doesn't work. How can i fix it?
EDIT 1
Here the complete part of code
char myvariable[16];
GetDlgItemTextA(hDlg, IDC_IPADDRESS, &myvariable[0], 16);
myThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThread, (LPVOID)&myvariable, 0, &myThreadId);
DWORD MyThread(LPVOID lpdwParam)
{
char *myvariable2 = (char *)lpdwParam;
....
}
EDIT 2
Doesn't work means that myvariable2 doesn't contains the text of myvariable
EDIT 3
char *myvariable = new char[16];
GetDlgItemTextA(hDlg, IDC_IPADDRESS, myvariable, 16);
myThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThread, (LPVOID)myvariable, 0, &myThreadId);
and the thread function:
char *myvariable2 = (char *)lpdwParam;
If you're doing something like this:
// ...
char myvariable[N] = "blablabla";
HANDLE hThread=CreateThread(NULL, 0, MyThread, (LPVOID)myvariable, 0); // however you should use beginthread to avoid troubles with the CRT
// ...
DWORD MyThread(LPVOID lpdwParam)
{
char * mystring = (char *)lpdwParam;
// ...
return 0;
}
and you don't get the correct characters by reading mystring, my guess is that, being myvariable allocated on the stack, it goes out of scope before MyThread gets the chance to run, thus you get the same kind of problems you encounter when you return a pointer to a local variable.
The solution would be to allocate dynamically your string:
// ...
char * myvariable = new char[N];
*myvariable=0;
strncat(myvariable, "blablabla", N); // this is equivalent to what the nonstandard strlcpy would do
HANDLE hThread=CreateThread(NULL, 0, MyThread, (LPVOID)myvariable, 0); // however you should use beginthread to avoid troubles with the CRT
// ...
DWORD MyThread(LPVOID lpdwParam)
{
char * mystring = (char *)lpdwParam;
// ...
// when you're done with mystring, remember to free it; even better, use a smart pointer
delete [] mystring;
// ...
return 0;
}
By the way, notice that, as already said in the snippets, if you plan to use CRT functions inside your newly created thread you shouldn't use CreateThread directly, but you should instead use the _beginthread/_beginthreadex functions, because otherwise some CRT per-thread structures may not get initialized correctly.
Addendum
i edited my code to use new char[16] but it doesn't work. When i cast the variable from LPVOID to char* inside the thread function i get only strange symbols
If you changed the code so that myvariable is now a pointer, you should remove the & from the call to CreateThread; & was superfluous when it was used with the array (in that case just using its name was enough), but now that myvariable is a pointer it is plain wrong, since using it on myvariable will provide the address of myvariable instead of the address stored in myvariable.
Long story short, remove that ampersand.
If your doing c++ casting, you will need to use const char* var = reinterpret_cast<const char*>(lpdwParam);. Just be careful though, if its a stack string, it'll probably pass out of scope before the thread uses it, if its a static string, you should use const to preventing any accidental overwriting of data