Gas cost calculator

I am refreshing my university knowledge on C++ due to a job interview and I am trying to understand everything in depth. Is there any reason for me to use pointers and dynamic memory features of C++ in this example?

It's not that clear to me when should I use these features.

#include <iostream>

using namespace std;

int main(){

const int range = 100; // Consumption is lt/100km
double * km = new double;
double * consumption = new double;
double * gas_price = new double;
double * gas_cost = new double;

cout << "*************************" << endl;
cout << "** Gas cost calculator **" << endl;
cout << "*************************" << endl;
cout << endl;
cout << "-> Enter distance in km: ";
cin >> *km;
cout << "-> Enter consumption (l/100km): ";
cin >> *consumption;
cout << "-> Enter gas price in euros: ";
cin >> *gas_price;

*gas_cost = *consumption * *gas_price * *km /range ;

cout << "-> Gas cost: [" << *gas_cost << "€]";
cout << endl;

}


In this minimal of an example, I would not use pointers or dynamic memory features.

As I read this code, I am more concerned about the fact that the code is not divided into logical functions instead of having main handle everything and that you are using namespace std;.

You should not use using namespace std; in your code, but rather specify which namespace you are using like this: std::cout. If you do use this, it can cause many problems.

You should also not have main handle all the work. You could, for example, have a method to calculate the gas cost, and pass it any required parameters.

Additionally, I would probably just initialize the values with -1.

double consumption = -1;
do {
std::cout << "-> Enter consumption (l/100km): ";
std::cin >> consumption;

if (!std::cin) {
std::cin.clear();
std::string s = "";
getline(std::cin, s);
}
while (consumption > 100 || consumtion < 1);


This will validate the consumption input, and also not let your program crash if the user inputs a string.

Validation is very important if your program expects input with certain specifications (in this case, it both expects a double and a value with a specific range).

• Thank you for the tips. Why do you initialize the values with -1 ? – Radolino Feb 22 '15 at 23:28
• They need to be initialized in case the first values entered are bad and you get to the comparison. -1 is often used as a flag value because it is out of the range of the real value. Any value out of the real value could be used, but -1 is commonly used, so I just used that. – user34073 Feb 22 '15 at 23:39
• -1? Why not just 0? – user25057 Feb 23 '15 at 2:04
• It could be 0 in this case, but -1 is used more often than 0 because many ranges are 0-x ranges, so it is more easily recognized as a flag than 0. – user34073 Feb 23 '15 at 2:20
• The while test would be better if it used a negative value of consumption as a termination condition, as there really are vehicles that have fuel consumption outside that range: en.wikipedia.org/wiki/Volkswagen_1-litre_car and en.wikipedia.org/wiki/M1_Abrams – jamesqf Feb 23 '15 at 4:40

Is there any reason for me to use pointers and dynamic memory features of C++ in this example?

No, absolutely not.

It's not wrong per se, and you'll still get the same output, but C++ doesn't require manual memory allocation in such cases. The same can be done by declaring local variables, which is what you should be doing here. Plus, you never free any of the allocated memory with delete, so you're causing memory leaks in several places. Regardless, you should just declare the variables on the stack.

They should look like this:

double km;
double consumption;
double gas_price;
double gas_cost;


The cin statements should then no longer have asterisks.

Moreover, consider moving the variables next to their respective cin statements, thereby maintaining a closer scope. This is an example of good practice in C++.

cout << "-> Enter distance in km: ";
double km;
cin >> km;

• How do you know when to use pointers and references ? – Radolino Feb 22 '15 at 23:30
• @RobDel: You would use references if, for instance, you wish to pass a variable to a function and modify that argument. However, for pointers, you hardly need them in C++. In C, they're mostly used for C-strings and arrays. – Jamal Feb 22 '15 at 23:36

If a program does dynamic allocation it should also delete whatever it allocated when it's no longer needed. But there's no need here for dynamic allocation. One major clue is that the code dereferences every use of every pointer. That pretty much says that they've merely values, and should be defined as such:

double km;
double consumption;
double gas_price;
double gas_cost;


That initial using namespace std; is a red flag: while it doesn't hurt anything here, it's a bad habit. Namespaces exist for a reason, and blowing them away like this will lead to confusing conflicts in more complex code. The name of std::cout is std::cout.

The use of endl is excessive. Inserting a newline (\n) starts a new line. std::endl starts a new line and flushes the output buffer. In a larger program this can make things very slow.

Finally, the code should check that the various input operations succeeded before attempting to use their results. Or, cleaner, write a function that prompts for input and returns the value; it can loop until it gets valid input (what if the user types 'd' in response to a prompt?), or it can throw an exception. The code can call that function in each of the places where it needs a value from the user.