Vector::at vs. vector::operator[] -- different behaviour [duplicate] - c++

This question already has answers here:
Vector going out of bounds without giving error
(4 answers)
Closed 8 years ago.
#include <iostream>
#include <vector>
#include <stdexcept>
using namespace std;
class sample
{
public:
sample()
{
cout << "consructor called" << endl;
}
void test()
{
cout << "Test function" << endl;
}
};
int main()
{
vector<sample> v;
sample s;
v.push_back(s);
try
{
v.at(1).test(); // throws out of range exception.
v[1000].test(); // prints test function
}
catch (const out_of_range& oor)
{
std::cerr << "Out of Range error: " << oor.what() << '\n';
}
return 0;
}
Why v[1000].test(); printing test function on the screen. I have added only one object in the vector. I agree I can access v[1000] becuase its sequential. But why it is giving the exactly correct result? Thanks in advance.

vector::at() explicitly throws out of bound exception while vector::operator is not doing that. By design.
Some std implementations support operator[] bounds checking in debug mode.
As your test() method is not accessing any instance variables and this then it can be executed without problem even this points to non-existent location.

Related

accessing the nullptr data [duplicate]

This question already has answers here:
Why am I able to make a function call using an invalid class pointer
(6 answers)
Does calling a method on a NULL pointer which doesn't access any data ever fail?
(3 answers)
When does invoking a member function on a null instance result in undefined behavior?
(2 answers)
Closed 4 days ago.
I ran into a problem with an uninitialised unique ptr, here is the code:
class Demo {
public:
Demo() {}
void noSegFault()
{
std::cout << "noSegFault" << std::endl;
}
void segFault() {
std::cout << "Address of data :" << &data << std::endl;
std::cout << "Before segfault" << std::endl;
data = 234;
std::cout << "After segfault" << std::endl;
}
private:
int data{123};
};
int main() {
std::unique_ptr<Demo> demoPtr{nullptr};
if (demoPtr == nullptr) {
std::cout << "demoPtr is null" << std::endl;
}
demoPtr->noSegFault();
demoPtr->segFault();
return 0;
}
Output:
demoPtr is null
noSegFault
Address of data :0
Before segfault
In this context, demoPtr is initialized with nullptr. I used to believe that accessing nullptr would inevitably lead to a segmentation fault. However, in this program, I can successfully call the noSegFault method and observe its output. Yet, if I attempt to access any variables of the nullptr object(invoking segFault method), a segmentation fault occurs.
So as per the output I can able to invoke the methods which doesn't use its member variables successfully without segmentation fault.Is it the expected behaviour?
godblot link: https://godbolt.org/z/G34c1jefb

error with vector::reverse_iterator in debug mode but not in release

I use reverse_iterator to look up my vector and using pop_back to erase elements.But it causes some error in debug mode. My code is this:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Student{
string name;
int score;
};
int main()
{
vector<Student> testVec;
testVec.push_back(Student{ "Lilei",50 });
testVec.push_back(Student{ "YangFeifei",80 });
testVec.push_back(Student{ "WuMing",80 });
for (auto it = testVec.rbegin(); it != testVec.rend(); ++it){
if (it == testVec.rbegin()) continue;
while (it != testVec.rbegin()) {
std::cout << &(*testVec.rbegin()) << ", ";
std::cout << &(*it) << std::endl;
testVec.pop_back();
std::cout << &(*testVec.rbegin()) << ", ";
std::cout << &(*it) << std::endl; // where error occur!
}
}
std::cout << "Hello World!\n";
}
This documentation for std::vector<>::pop_back() says that:
Iterators and references to the last element, as well as the end() iterator, are invalidated.
Therefore, your it iterator is invalid after you called pop_back(). The behaviour of dereferencing this iterator is undefined, so your program's behaviour will be unpredictable.
For your particular case, it's possible that in debug builds there are some additional methods for the runtime to determine that you have made a mistake, but these checks may be costly for performance so may not be included in a release build. In any case, the behaviour is not guaranteed. The solution is to not use it after calling pop_back().

Null Object is calling A Method but Program is not crashing.. .How ... Why? [duplicate]

This question already has answers here:
What will happen when I call a member function on a NULL object pointer? [duplicate]
(6 answers)
Closed 4 years ago.
I was trying some code. Mistakenly wrote below code (Luckily Now)
Snippet 1
#include<iostream>
using namespace std;
class A {
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void print() { cout << "A::print()=>" <<this<< endl; }
};
int main() {
A* a = new A;
a->print();
delete a;
a = NULL;
cout << a << endl;
a->print();
return 0;
}
As I know, since I have deleted "a", the program should have crashed (Not so true now). But it did not. Can some please explain the reason behind this. The output image is also attached.
But As soon as I include any member variable in the above program, it crashes.
How ? Why ? Please see Program 2.
Snippet 2
class A {
int val;
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void print() { cout << "A::print()=>" <<this << val << endl; }
};
int main() {
A* a = new A;
a->print();
delete a;
a = NULL;
cout << a << endl;
a->print();
return 0;
}
The Above program is crashing. Why not the 1st program?
PS: There are chances that it may be the duplicate question. I tried to find the question like this but couldn't find. Though I got this question, I feel it's not the same as I am looking for.
The first one doesn’t dereference any memory pointed by anything, therefore it might not crash. You’re only printing out this which is a pointer value and you’re not dereferencing it. Note that this doesn’t mean it’s ok and will always work! It is definitely not allowed and shouldn’t be done. What happens when this is done is undefined.
Your second example actually tries to use a member variable which means an attempt is made to access memory that isn’t valid. This is also undefined behavior and may cause a crash, or something else. It is undefined.

is it ok to return a local variable by move?

I'm reading Nicolai M. Josuttis's 2nd edition of "The C++ Standard Library" covering C++11 , where in Chapter 18: Concurrency, page 969 and 970 give a sample program:
// concurrency/promise1.cpp
#include <thread>
#include <future>
#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>
#include <functional>
#include <utility>
void doSomething (std::promise<std::string>& p)
{
try {
// read character and throw exceptiopn if ’x’
std::cout << "read char (’x’ for exception): ";
char c = std::cin.get();
if (c == ’x’) {
throw std::runtime_error(std::string("char ")+c+" read");
}
...
std::string s = std::string("char ") + c + " processed";
p.set_value(std::move(s)); // store result
}
catch (...) {
p.set_exception(std::current_exception()); // store exception
}
}
int main()
{
try {
// start thread using a promise to store the outcome
std::promise<std::string> p;
std::thread t(doSomething,std::ref(p));
t.detach();
...
// create a future to process the outcome
std::future<std::string> f(p.get_future());
// process the outcome
std::cout << "result: " << f.get() << std::endl;
}
catch (const std::exception& e) {
std::cerr << "EXCEPTION: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "EXCEPTION " << std::endl;
}
}
Here string s is a local variable but moved to return.
However, as programs quited calltree level by level, the stack memory will be release. Would this be a problem when call stack unwinds?
Note: this question is different from c++11 Return value optimization or move? : this question is about move is potentially dangerous, while the other question is about whether actively prohibits copy elision or let compiler decide.
Unless otherwise specified, all standard library objects that have been moved from are placed in a valid but unspecified state. Valid means it can be safely destroyed (e.g on stack unwinding). In your example s is not returned but stored in promise but if it was returned in normal way return s; compiler could implicitly call return move(s);.
This is not a problem.
Move semantics moves the internal value of a variable not the variable itself. So you still have a separate destination string to the source string.
The whole exercise works ostensibly like a copy except that afterwards the source object has changed its value to an unknown quantity.
It is still a valid object (of unknown value) and will be properly destroyed when the stack unwinds.

C++ code error in my practice code [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
Can you please help me out with this issue?
#include <iostream>
#include <cstring>
using namespace std;
class A
{
public:
char str[4];
A()
{
str = "C++";
cout << "Constructor A" << endl;
}
void display()
{
cout << str << " is your name" << endl;
}
};
int main()
{
A a;
a.display();
return 0;
}
It gives the following errors:
**************************Error**********
StringProg.cpp:9: error: ISO C++ forbids initialization of member "str"
StringProg.cpp:9: error: making "str" static StringProg.cpp:9: error: invalid in-class initialization of static data member of non-integral type "char [4]"
StringProg.cpp: In member function "void A::display()":
StringProg.cpp:17: error: "str" was not declared in this scope
**************************
There are quite a few issues with C arrays that prevent you from doing what you want to do.
String literals have type of const char[n] (n being their length + 1 for \0 character). To use them in C Standard Library functions, they decay to const char*, which don't carry the size of the string, and in order to find it, the strings need to be traversed (every character being looked at and compared to \0)
As a consequence, array assignment operator would need to be rather nontrivial; this isn't provided by the language, and you have to use library functions like strcpy to move the literal into your usable memory. In other words, you can't assign C arrays like other values.
Arrays function in a very primitive way; they don't have operators for comparison, it's harder to pass them to functions and store in the classes properly.
And so, because of all the above...
Prefer std::string to char[]:
class A {
std::string str;
public:
// prefer constructor init list
A() : str("C++") {
// your line would work, too
std::cout << "Constructor A" << std::endl;
}
void display() const {
std::cout << str << " is your name" << std::endl;
}
};
int main()
{
A a;
a.display();
// return 0; is unnecessary
}
Some "rules of thumb" (rules of thumbs?): if you need more than one element, start with vector<>. Never use C arrays. string is one element, not an "array of characters".
Try the following
#include<iostream>
#include<cstring>
class A
{
private:
char str[4];
public:
A() : str { "C++" }
{
std::cout << "Constructor A" << std::endl;
}
void display() const
{
std::cout << str << " is your name" << std::endl;
}
};
int main()
{
A a;
a.display();
return 0;
}
The program output is
Constructor A
C++ is your name
Take into account that arrays do not have the copy assignment operator. Thus this statement in your program
str = "C++';
even if to update the typo and write
str = "C++";
is invalid.
You could use standard C function strcpy declared in header <cstring>. For example
#include <cstring>
//...
A()
{
std::strcpy( str, "C++" );
std::cout << "Constructor A" << std::endl;
}