0
is const and default argument safe
Refer code below: https://www.sololearn.com/en/compiler-playground/c1v6P04B0TJg It was someone's interview question and he does not recall fully. But assume that it was as per above code. Provided that, I believe this code is always safe and there would not be a memory issue. Is my understanding correct? If it is not, could anyone please suggest? Also, what if "string m_s;" member variable itself as const string? It remains safe still. Correct? https://sololearn.com/compiler-playground/c1v6P04B0TJg/?ref=app
17 ответов
+ 3
passing objects as argument to a function as both const and reference is generally most of the time the best technique, but you should understand 100% how it works, i use it always when is possible, it increase speed specially if you working with huge data or when do this in loop or very often in runtime and also its a bit safer than using pointers.
When pass an object by reference it actually pass the pointer of it, the difference between pointers and references is that pointers can point to null, but reference not, reference always point to something.
Using const, shows that this object will not edited inside the constructor or function.
In your constructor you deep copy the string of the argument to a new string inside the class. This is safe as long you copying the contents of string t and not just it's pointer.
Will be not safe if in your class instead of what you have now, you had any of these:
string& m_s;
const string& m_s;
string* m_s;
const string* m_s;
+ 3
as long as the code does not try to modify the argument... there is the distinction between initialization and assignment or modification.
+ 3
Ketan Lalcheta yes correct, i wanted to say that string has its own copy constructors, so as you got it right now, string internally will copy all the contents, so every object not affecting each other
Im sorry, what cause error for you? I talking for the 2nd code (the 1st one not opening for me). The 2nd code I tried it and it run as expected
+ 3
Ketan Lalcheta it does not compile because the argument is const and you try to store it to a non-const variable
+ 2
Bob_Li your code that has "quirky behavior" is normal and not has to do with reference or/and const. Same results will have if get address of any int variable, cast it to char* and pass it to that function...
If pass a array of characters, null terminated, there is no casting. the string has a constructor getting a const char* argument, but it doesn't know the length of the string, so it will find the 1st character has 0 value, then, it copying the contents of buffer, length, size of buffer and other things, it pass its pointer to the string& m and when constructor return, this string object will destroyed
However, depends on the compiler (optimizations) or language (can't remember), it may not even copy the whole buffer, but only its pointer, bugfer size and length, that means technically if call string.c_str() and keep this pointer in your class, it will be valid forever even after string object destroyed, but don't do that 🤣
+ 1
how is "Lalcheta" a const char?
I did some experimenting and found some quirky behavior though, so maybe these are some things you should not pass as arguments.
https://sololearn.com/compiler-playground/c7xH7nm2cA7L/?ref=app
+ 1
My bad. Typo. Not const char but const char*
Thanks for code snippet.
I checked your code and confused by the uncomeented code itself. Why should we pass char or const char to function which takes string as an input? It does mot make much sense. However, it should have given compile time error. Why no error is thrown?
+ 1
The idea came from your typo.😅
I think the default value in the function parameter is acting like a buffer and the char is being implicitly cast to string.
Since it does not throw an error, it is a situation that we should be aware of.
+ 1
john ds , As string class has their own implementation of copy assignment and copy constructor, there is no chance of doing deep copy from object of string class I had. Right? So, my class is always safe. Correct?
However, I could not get why ref or const ref member will cause the problem? Same for pointer as well. Why it cause the problem?
+ 1
Hi john ds , both code in question are same only. One was attached from web version of sololearn and same could not be opened from android app version. Second code is same which was added from android mob app.
I had no doubt of code working for sample scenarios I had. I just wanted to make sure whether it will fail in other scenarios or it's absolutely safe code.
Also many thanks for explaining why Bob_Li code behaves abnormally due to missing null char for char*
What I fail to understand still is about scenarios you mentioned. Do you still feel below four member had caused issue or not :
string&
Const string&
String*
Const string*
Or class and constructor I had in sample code would work safely for above for members also?
+ 1
john ds my bad.
Here is code which shows failure in case of const string ref as it allocates memory once and that goes released after constructor call.
If it would not have been a const ref, copy constructor gets called (like first case) and new memory is allocated which saves us.
Many thanks for this clarification 👍
https://sololearn.com/compiler-playground/cDDeG9sAocbx/?ref=app
+ 1
Bob_Li yes, always should understand what parameters a function need. sometimes compiler can detect those mistakes and throw a warning, but string can accept anything, it is actually a vector<char>
0
Do you mean I should not modify anything insider constructor body? If so, I don't have a purpose to modify input const string. Does this make code safe?
I got doubt as string is const string ref and I have default argument of const char.
0
Ketan Lalcheta i see the reason of 2 codes now, thanks.
This exact code is safe, but if is safe or not in similar scenarios depends from many factors. First of all what exactly you mean "similar"? You have to keep in mind reference is a pointer and using those will be safe, as long the object that pointing too not destroyed.
About your 3rd part, you mean 'null character (zero terminated array)' not null pointer as this is something different.
0
The scenarios i mentioned are unsafe examples. Reference is a pointer, if you store them in your class, it requires the object that the pointer points to, not be destroyed as long test1 object exists.
Your constructor gets a reference to a string object. The default value "Lalcheta" and the "Ketan" you passing to the constructor are not string objects, but const char* (array of chars), so somewhere must create those string objects first.
Here is your code:
test1(const string& s = "Lalcheta")
Here is more analytical:
test(string& m = string("Lalcheta", 8))
{
//some code
}
As you can see there is a hidden string object created inside the test1() scope.
Whatever is created inside a function are local variables, when the function finish all local variables will get destroyed automatic.
This range when a object is "alive" named "scope of variable".
As you can see the secret string object is valid only in test1 scope. After you return from test1, any pointer/reference to it will be unsafe to used.
0
Original code is as below:
class test1
{
public:
test1(const string& s = "Lalcheta") : m_s(s) {}
void display()
{
cout << m_s << endl;
}
string m_s;
};
If I had class variable as string ref as below:
class test1
{
public:
test1(const string& s = "Lalcheta") : m_s(s) {}
void display()
{
cout << m_s << endl;
}
string& m_s;
};
Code does not even compile. So, that is not an issue for us. Is that something you wanted to share for string ref or anything else ?
0
john ds
right, as you explained, there is an implicit char* to string conversion. As long as you input valid types, there should be no problem.
But the conversion unfortunately allows some edge cases to pass without raising errors. C++ 's aim to keep the compatibility with C is a footgun in this case. So I feel that avoiding the habit of using C type string in C++ is the way to go. C++ string might be bigger, but it is safer.