how to initialize string pointer? - c++

I want to store the static value in string pointer is it posible?
If I do like
string *array = {"value"};
the error occurs
error: cannot convert 'const char*' to 'std::string*' in initialization

you would then need to write
string *array = new string("value");
although you are better off using
string array = "value";
as that is the intended way to use it. otherwise you need to keep track of memory.

A std::string pointer has to point to an std::string object. What it actually points to depends on your use case. For example:
std::string s("value"); // initialize a string
std::string* p = &s; // p points to s
In the above example, p points to a local string with automatic storage duration. When it it gets destroyed, anything that points to it will point to garbage.
You can also make the pointer point to a dynamically allocated string, in which case you are in charge of releasing the resources when you are done:
std::string* p = new std::string("value"); // p points to dynamically allocated string
// ....
delete p; // release resources when done
You would be advised to use smart pointers instead of raw pointers to dynamically allocated objects.

As array is an array of strings you could try this:
int main()
{
string *array = new string[1];
array[1] = "value";
return 0;
}

You can explicitly convert the literal to a string:
std::string array[] = {std::string("value")};
Note that you have to define this as an array, not a pointer though. Of course, an array mostly makes sense if you have more than one element, like:
string array[] = {string("value1"), string("value2"), string("etc")};

Related

Adding a string to a string pointer

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 can I use a pointer to a pointer to a string object and use the pointer to the pointer to call size() member function of the string object

I need some advice on how to approach this problem. I need to assign a pointer to a pointer that points to a string object that contains the word. I wish to use the pointer to the pointer to call the size() member function of that string object. Any help on solving this problem or how I can approach this problem with an example would be great.
Apply * once per indirection level, like in the declaration of the variable.
std::string s = "tjena"; // A string
std::string *sp = &s; // A pointer to a string
std::string **spp = &sp; // A pointer to a pointer to a string
(**spp).size(); // Call it like this
(*spp)->size(); // Or like this
(*sp).size(); // Or like this
sp->size(); // Or like this
Simply dereference the pointers twice to reach the actual string object.
Given:
string word = ...;
string *pword = &word;
string **ppword = &pword;
You can do this:
int size = (*ppword)->size();
Or this:
int size = (**ppword).size();

How can I call "delete" on the elements of a "vector<string>" when each string is created by a "new char[]"?

I have a vector of strings, however these strings are created by assigning to them an array of characters. This array is created dynamically in the heap with new. I know that it's a good practice to free the memory that you allocate in the heap, however I'm not sure how I should free the memory of this vector.
When I try to do something like this:
for(i = 0; i < myVector.size(); i++)
delete myVector[i];
It gives me this error:
Expression must have pointer type
Here is how I declare the vector
vector<string> myVector;
char* s1 = new char[2];
s1[0] = 'a';
s1[1] = '\0';
myVector.push_back(s1);
char* s2 = new char[2];
s2[0] = 'b';
s2[1] = '\0';
myVector.push_back(s2);
//etc..
What should I do in this case?
Since you use a vector<string> and because std::string objects manage their own memory, you do not need to delete the elements of the vector: the strings have copied the content that you passed to them on creation.
However, you need to delete the C strings that you allocated with new[]. You should do it right after you created your string object: once the string is created, the character data can be safely deleted:
char s1 = new char[2];
s1[0] = 'a';
s1[1] = '\0';
myVector.push_back(s1);
delete[] s1; // Here
Note that you picked a rather roundabout way of creating strings: you can accomplish the same exact thing by calling
myVector.push_back("a");
Another possibility would be the use of std::string, i.e. std::vector<std::string>.
In that case you can't delete the initial memory anymore, unless you kept the pointers (which is pointless, because the std::string will keep ist own string copy anyway).
Considering your posted code, you should keep in mind that std::string will create ist own copy of the string you passed in the constructor, even though the constructor isn't visible due to using implicit type conversion.
Just free (delete) the memory right after you've put the string inside the vector. The string won't be affected by this.

Converting from std::vector<> to a double pointer?

I was wondering out of curiosity if it is possible to cast a std::vector<> to a double pointer.
I've never had an issue passing a std::vector as a pointer in this fashion:
std::vector<char> myCharVector;
myCharVector.push_back('a');
myCharVector.push_back('b');
myCharVector.push_back('c');
char *myCharPointer = &myCharVector[0];
So I was curious if it was possible to assign the address of the pointer in a similar way to this:
char *myPointer = "abc";
char **myDoublePointer = &myPointer;
I've tried:
char **myDoublePointer = (char**)&myCharVector;
But it doesn't work. Is there any way of achieving this?
You already know that &myCharVector[0] is a pointer to char. So if you store it in a variable:
char *cstr = &myCharVector[0];
then you can take the address of that variable:
char **ptrToCstr = &cstr;
But simply dereferencing twice like this:
char **ptrToCstr = &(&myCharVector[0])
is invalid because the value (&myCharVector[0]) isn't stored in memory anywhere yet.
In C++11, you can do:
char *myCharPointer = myCharVector.data();
But you cannot take the address of the return value of data() because it does not return a reference to the underlying storage, just the pointer value.
If the purpose is to be able to change what the pointer is pointing to, then you may really want a pointer to a vector, rather than a pointer to a pointer to a char. But, the STL doesn't let you change the underlying pointer within the vector itself without going through the regular vector APIs (like resize or swap).
You most definitely can't do this. std::vector and a char ** are completely different types of objects and you can't just "cast" one to another.
The reason you were able to do char *myCharPointer = &myCharVector[0] is that myCharVector[0] gives you a char, and thus &myCharVector[0] gives you the address of that char, which you can assign to a char *.
The only way you could convert a full std::vector into a char * (not char **) is to loop over your std::vector and construct a char * from the data manually.
For instance something like:
char *ptr = malloc(myCharVector.size()+1);
for (unsigned int i=0; i < myCharVector.size(); i++) {
ptr[i] = myCharVector[i];
}
ptr[myCharVector.size()] = 0;
Then ptr will be a C string of chars.

Char array gives error when initializing

It can be simple but I m new about c++
In char arrays we can let the compiler to count number of characters in the string like
char myarray[]="stringvar";
its ok, but if i change the code as below,the compiler gives error
string myvar = "stringvar";
char myarray[] =myvar;
error: initializer fails to determine size of myarray
Why is that?
You can do this:
string myvar = "stringvar";
const char * myarray = myvar.c_str(); //immutable string
In this case, the data whichmyarray points to, lives as long as the lifetime of myvar.
However, if you want a mutable string or, a string which may last longer (or shorter) than the lifetime of myvar, then you've to allocate memory yourself as:
char * myarray = new char[myvar.size()+1]; //mutable string
std::strcpy(myarray, myvar.c_str());
//you've to deallocate the memory yourself as:
delete [] myarray;
You cannot assign an std::string object to initialize and create a character array.
You will need to copy the std::string in to the array.
strcpy(myarray,myvar.c_str());
There is error, because char myarray[] is equivalent to char* myarray. It is just a pointer to char. So you need a compatible initializer there (like char* or const char*). But you are trying to pass an instance of string class, that is not a pointer.
If you wish to assign myarray to a string (make it point to the same location) you may do this
char myarray[] = const_cast<char[]> myvar.c_str();
But in any case, its not good idea, until you definitely know what you're doing.
string myvar = "stringvar"
char* myarray = (char*)myvar.c_str();
It should work.