I am using c++.
I want to initialize pointer of string. I have been doing it using :
string *strPtr = new string("abcd");
But I don't want to use heap memory. Use somthing like this :
string *strPtr;
// initialize with "abcd"
How can I do it using stack memory?
You can declare a string on the stack and then take the address of it:
std::string str{"abcd"};
std::string* ptr_str = &str;
But I'm sure it would be more convenient for you to handle a reference, a smart pointer, or maybe a std::string_view. Raw pointers should be used in some very specific cases nowadays.
Like this:
string str("abcd");
string *strPtr = &str;
Sometimes you can get away with using alloca() to allocate memory on the stack, you'd need to allocate twice, once for metadata and once for data and then reinterpret_cast...
Related
As part of a small program i need to convert a string to a char array. I want to use the strncpy_s() method but I keep getting an assertation saying that the "buffer is too small".
This is what my code looks like:
char* ostr = new char[sizeof(str)+1];
strncpy_s(ostr, sizeof(ostr), str.c_str(), sizeof(ostr));
Hope someone can help me.
The variable str is, it seems, a std::string object. The size of the object is the size of its member variables, which for std::string commonly is a pointer (to the actual string) and variable for the length of the string.
If you want to get the length of the wrapped string you need to use the length function.
Furthermore, there is another problem with your call to strncpy_s: You do sizeof(ostr), which is the size of the pointer, not the size of the memory it points to.
Lastly, if you want to pass a pointer to the string to a C function, then either use str.c_str() directly in the call. Or if the C function needs to modify the string (but not reallocate it) then use e.g. str.data() or &str[0].
If the C function needs to reallocate the data then you can't use new[] to allocate it. You need to use malloc (or possibly strdup if your system have it).
Is it possible to add a string to a string pointer in C++?
Not working example:
String* temp;
temp[0] = "string";
Just like it's possible in:
String temp[3];
temp[0] = "string";
Before suggesting to just use a normal array or copy it to a different fixed array, the string pointer needs to be returned in a function. Eg.
String* SomeClass::toArray(String str)
I am also open to other suggestions how I can return an array from this function.
Independing of what is String this code snippet
String* temp;
temp[0] = "string";
if it is compiled results in undefined behaviour because the pointer temp either has an indeterminate value (if it is a local variable) or NULL and you may not derefence it.
Provided that this code snippet
String temp[3];
temp[0] = "string";
is valid you could write for example
String* other_temp = temp;
other_temp[0] = "string";
you can't add anything to POINTER, pointer is just pointing to some memory.
You need first to have some instance, like in your second example String temp[3]; you are creating three instances of String.
So String temp; will create local instance of String, then to get it's pointer you can use String * tempPtr = &temp;, but I don't see why you would want that, as you can use temp as is... like temp.clear(); or whatever functions the class String has (see it's API).
Edit about returning String pointer.
That's sort of unfortunate C++ API design. So who will own the memory of that instance?
For example:
String* SomeClass::toArray(String str) {
String result;
// BUG, DO NOT DO THIS!
return &result; // returns pointer to local stack variable
// which gets released *here*, invalidating the pointer
}
String* SomeClass::toArray(String str) {
String *result = new String;
return result; // returns pointer to global heap
// now if the upper layer of code will not call "delete" on it
// you have memory leak
}
BTW, from the "toArray" name it looks like you want array of String instances, not String pointer. So that functions should be rather defined as String[] SomeClass::toArray(String str), still having the same problem with memory ownership.
What I would do is not return an array.
maybe void SomeClass::toArray(const String & str, std::vector<String> & array), filling up the data into array vector.
I do not know how much you use C++ on arduino, if std::vector is OK, or not, but having a class for String feels like vector<> will be OK too, especially if you are wasting your stack by passing copy instance of String instead of reference. (unless String is some macro/typedef for char[], please, don't tell me that... I mean, even C++ can be written in low memory footprint way, you don't have to hardwire arrays everywhere, if you avoid unnecessary allocation of temporary instances of C++ classes).
How do I do this thing.
char* ToString(int num) {
char* str = new char[len(num)];
//conversion
return str;
}
And by calling this.
string someStr = ToString(someInt);
Should I free the someStr here?
I know I always need to delete whenever I use new.
And what if I call this function multiple times, do I allocate memory and just leaving them behind not using it?
You should avoid this practice altogether. Either return a std::unique_ptr, or deal with std::string directly. It is not clear from your code what exactly you are trying to do, so I can't offer specific solutions.
Note that this initialization:
string someStr = ToString(someInt);
will only work properly if you return a null-terminated string, but it leaks resources regardless.
See this related post.
You need to call delete once for every call to ToString. You also can't initialise a std::string with an allocated char array in the way your question hints at - that'd leak the returned memory, with your someStr variable having copied it.
The easiest/neatest thing to do would be to change ToString to return std::string instead. In this case, memory used by the string will be automatically deleted when the caller's variable goes out of scope.
I ran your code under valgrind with --leak-check=full, it reports num size of memory leak.
Call new/delete, new [] /delete [] in pair is the only way to keep memory cycled.
I am not sure what's you trying to do, if you want to convert integer types to string, C++ has a few options:
// std::to_string(C++11) e.g:
{
std::string str = std::to_string(num)
}
// std::stringstream e.g:
{
std::string str;
std::stringstream ss;
ss << num;
ss >> str;
}
// boost::lexical_cast e.g:
{
std::string str = boost::lexical_cast<std::string>(num);
}
// itoa(c function)
{
char buf[MAX_INT_DIGITS]; // MAX_INT_DIGITS == 12 ("-2147483648\0")
itoa(num, buf, 10);
std::string str(buf);
}
You're ToString function should return a std::string, if you then just assign the value to a std::string. No reason to deal with dynamically allocated memory here.
someStr is a copy. You have allready a leak. You need to temporally save the value of the returned pointer and after constructing the string delect it. This is normaly the job of the smart pointers.
EDIT:
No,
char* temp = strs; delete [] str; return temp;
will something undefined. But:
char* temp =ToString(someInt); string someStr(temp);delete []temp;
will work. But this is only for you to understand the idea. This can be made for you if you return a unique_ptr. And I'm assuming this is a kind of general question of returning a memory that have to be free after that, in with case unique_ptr and shared_ptr are a solution. In this particular case you can just create a string, modify it and return it simply. All the memory manage will be made for you by the string class. If you really only need to allocate “space” in the string, you can do:
String Str; Str.reserve(len(num));
I have a CEdit and I want to extract the data using this.
wchar_t *temp = (wchar_t*)dialog.editbox.GetBuffer(0);
dialog.editbox.ReleaseBuffer();
Now i want to save this text in a object pointer like this:
selectedShape->setText(temp);
This work perfect, but only as long as you are in the scope of the method, because when I do a file save later, the text is not in the object anymore.
Does anybody know how I can save this wchar_t* for later?
As #Prætorian says, your code seems to be missing a step of where you work with a CString class whose buffer you are getting.
http://msdn.microsoft.com/en-us/library/aa314880(v=vs.60).aspx
If at all possible, avoid using dynamic memory solutions. Instead, pass around your temp by value as a CString object that will manage its own memory. The stock Window setText functions take string pointers (which CString can implicitly cast to) and will copy the underlying string data. If you write your own objects, hold CString objects as members by value.
(I'll add my usual "The 90s called, they want their framework back" disclaimer here. Try Qt.)
The temp pointer is pointing to data that goes out of scope, so you'll need to dynamically allocate memory to store the value. Something like this should work:
// Updated to use wstring, thanks praetorian
std::wstring tempStr((wchar_t*)dialog.editbox.GetBuffer(0));
Or:
int length = /*figure out the length here*/;
wchar_t *temp = new wchar_t[length];
memcpy(temp, dialog.editbox.GetBuffer(0), length*sizeof(wchar_t));
// dont forget to delete it like this: delete [] temp;
how do you implement substring in C++ that returns pointer to char? (takes pointer to the first letter)
say something like char* substr(char* c, int pos, int lenght)
I use methods of the std::string class.
Edit:
say something like char* substr(char* c, int pos, int lenght)
This isn't a function that it's possible to implemement well. To create a substring, you need memory:
Same memory as original string: did you mean to overwrite the original string? Is the original string writeable?
New memory: is the caller going to invoke the delete[] operator on the pointer which it receives from your substr function (if it doesn't, there would be a memory leak)?
Global memory: you could reserve a fixed-length buffer in global memory, but that's all sorts of problems (may not be long enough, will be overwritten when someone else calls your substr).
The right way to do it is to return a std::string instance, which is what the string::substr method does, as shown in Graphics Noob's answer, because the std::string instance (unlike a char* instance) will manage the lifetime of its own memory; and if you then want a char* instance from the std::string instance, you can get that using the c_str() method.
Is this the functionality you are trying to replicate?
http://www.cplusplus.com/reference/clibrary/cstring/strstr/
str.substr(int,int).c_str()
Will return the substring as a const char* but be careful using it, the memory containing the string will be invalid at the end of the statement, so you may need to surround it with a strcpy() if you want to store the result. Or better yet just break it up into two lines:
std::string str2 = str.substr(int,int);
const char* cstr = str2.c_str();
You'll need to do a strcpy() to safely get rid of the const.
The ints refer to the parameters for the substring you're trying to get.