Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two almost identical C++ program, one runs well but the other get runtime error [closed]

Compare the following two pieces of code:

1.

#include <iostream>
using namespace std;
class B{
public:
    int val;
};
int main(){
    B *b;
    int t = 0;
    b->val = 1;
    cout << 123 << endl;
    return 0;
}

2.

#include <iostream>
using namespace std;
class B{
public:
    int val;
};
int main(){
    B *b;
    b->val = 1;
    cout << 123 << endl;
    return 0;
}

Both versions compile. Code #1 runs good but code #2 gets runtime error.

I'm compiling using C++11 and running a windows machine.

That really confuses me. Can anybody tell me the reason?

like image 855
Charles Gao Avatar asked Mar 07 '13 07:03

Charles Gao


People also ask

What causes runtime error in C programming?

These errors indicate either a bug in your app's code, or a condition that the runtime library can't handle, such as low memory. End users of your app may see these errors unless your write your app to prevent them, or to capture the errors and present a friendly error message to your users instead.

What happens when a program is running and there is a runtime error?

A runtime error occurs when a program is syntactically correct but contains an issue that is only detected during program execution. These issues cannot be caught at compile-time by the Java compiler and are only detected by the Java Virtual Machine (JVM) when the application is running.

Which of the following is a runtime error in C?

The runtime errors detected by Reactis for C include: Overflow Numeric calculations which produce a result too large to represent. Divide by Zero Dividing a numeric value by zero. Invalid Shift Shifting an integer value by an amount which produces an undefined result according to the C standard.


3 Answers

Both are wrong. The b pointer is uninitialized, so you should not be accessing memory through it.

B *b;
b->val = 1;

So you got lucky when one of them crashed.

The other one you got unlucky, and it didn't crash.

Fixes

You can remove indirection...

B b;
b.val = 1;

Or you can allocate it...

std::unique_ptr<B> b(new B());
b->val = 1;
like image 107
Dietrich Epp Avatar answered Sep 19 '22 17:09

Dietrich Epp


You are de-referencing an uninitialized pointer here

b->val = 1;

The location the pointer points to is undetermined: it could point anywhere.

Following this pointer is undefined behaviour (UB), which means anything can happen, which is what you are seeing.

What is really happening is that you are writing a value to a segment of memory that you shouldn't. There is no way of knowing what is located there, and the C++ standard can make no promises about possible outcomes. It just calls this UB. It is up to you to avoid these situations.

like image 29
juanchopanza Avatar answered Sep 21 '22 17:09

juanchopanza


The problem is that you are using an uninitialized pointer: B* b;. In C and C++, built-in types are not initialized upon creation: they just hold junk.

The solution to your problem is simple: do not use a pointer. B b; will create a class instance and call its constructor.

Code #1 runs good but code #2 gets runtime error.

In Standardese parlance, both code exhibit undefined behavior. This means that pretty much anything can happen and that comprises seemingly working (ie, there might be an error but there is no visible symptom).

like image 38
Matthieu M. Avatar answered Sep 18 '22 17:09

Matthieu M.