Reputation: 2984
A friend of mine is starting his programming/C++ journey so I told him to play around with loops and arrays.
He made a simple console program to read integer and compute the average.
#include "stdafx.h"
#include <iostream>
#include <math.h>
using namespace std;
int largeurTab;
int nombre;
int affNombre = 1;
int tableau [] = {nombre};
float moyenne;
int _tmain(int argc, _TCHAR* argv[])
{
//Saisi de la largeur du tableau
cout << "Veuillez saisir la largeur desire pour le tableau!" << endl << "Largeur : ";
cin >> largeurTab;
//Saisi des nombres du tableau
for (int i = 0; i < largeurTab; i++)
{
cout << endl << "Nombre " << affNombre << endl;
cin >> nombre;
tableau [i] = nombre;
affNombre += 1;
}
//Affichage * pour ligne séparation
for (int i = 0; i < 45; i++)
{
cout << "*";
}
cout << endl << "Voici le(s) nombre(s) que vous avez saisi :" << endl;
affNombre = 1;
//Affichage des nombres du tableau
for (int i = 0; i < largeurTab; i++)
{
cout << endl << "Nombre " << affNombre << endl << tableau[i] << endl << endl;
moyenne += tableau[i];
affNombre += 1;
}
//Affichage * pour ligne séparation
for (int i = 0; i < 45; i++)
{
cout << "*";
}
//Affichage et calcul de la moyenne des nombres saisi dans le tableau
cout << endl << "La moyenne des nombres saisi est de : " << moyenne/largeurTab << endl;
system("PAUSE");
return 0;
}
I always thought that C++ arrays were static and if I wanted something dynamic I had to go for pointers or vectors etc. Found this that kinda share the thoughts I have.
The part that bothers me is
int nombre;
int affNombre = 1;
int tableau [] = {nombre};
At first I thought that since nombre was not initialised, it was set to some very big integer by default so his array has a very big capacity... but after some debugging i'm not so sure about that.
So how is this working exactly ?
edit: I know this is wrong. I know he should be using a vector. But this code is working. The output value is valid. I just wanted to know technically how does this thing works.
Upvotes: 0
Views: 307
Reputation: 858
What is happening here is that tableau
is being treated as a pointer and you are writing to where ever it is pointing.
Here is an article of how variables are laid out in memory:
http://www.geeksforgeeks.org/memory-layout-of-c-program/
In the article tableau
is laid out in "initialed data" (only because it has the = {nombre};
) which has read-write access, meaning that if he had more than one global initialized array like tableau
, lets say foobar
he could overwrite the values in tableau
by writing to foobar
. And to make this worse, if you used a big enough index for either tableau
or foobar
you could start to overwrite the other global's.
Here is example of foobar
over writing tableau
:
#include <iostream>
#include <math.h>
using namespace std;
int largeurTab;
int nombre = 0;
int affNombre = 1;
int tableau [] = {nombre};
int foobar [] = {nombre};
float moyenne;
int main(int argc, char* argv[])
{
cout << "addrs of affNombre " << &affNombre << endl;
cout << "address of tableau " << tableau << endl;
cout << "address of foobar[1] " << &foobar[1] << endl;
cout << "address of foobar " << foobar << endl;
cout << "address of moyenne " << &moyenne << endl;
foobar[1] = 666; // this is all evil
cout << "foobar[0] " << foobar[1] << endl;
cout << "tableau[0] " << tableau[0] << endl;
return 0;
}
The final output will be tableau[0] = 666
and notice we didn't directly write to it.
This is was compiled in Microsoft visual studio.
Here is an example of it runing on Codepad.org, with moyenne being over written: http://codepad.org/Y1JMC8V5
Upvotes: 0
Reputation: 15872
int nombre;
int affNombre = 1;
int tableau [] = {nombre};
This does not create a dynamic array; it initializes a pointer to an array to 1. If your friend is looking to learn C++, I'd encourage them to take advantage of the C++ constructs (e.g. vector
). This entire program can be written in about 7 lines of C++ utilizing C++ constructs:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> v;
std::cout << "Enter values to average (Ctrl+Z to finish): ";
std::copy(std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), std::back_inserter<std::vector<int>>(v));
double result = std::accumulate(v.begin(), v.end(), 0.0) / v.size();
std::cout.precision(8);
std::cout << "Average = " << std::fixed << result;
return 0;
}
Upvotes: 2
Reputation: 322
int nombre;
int affNombre = 1;
int tableau [] = {nombre};
Above piece of code declares "tableau" array of size 1 with its value as nombre.
However, I think you running into memory corruption with following piece of code
//Saisi des nombres du tableau
for (int i = 0; i < largeurTab; i++)
{
cout << endl << "Nombre " << affNombre << endl;
cin >> nombre;
tableau [i] = nombre;
affNombre += 1;
}
You have an array tableau of size 1 elements. But you are looping for largeurTab and inserting that many elements in tableau but it can only hold single element legally. So you are actually running into buffer overflow.
It is just luck that your program is running fine. Please use vector as someone else already recommended or dynamically allocate the array.
Upvotes: 0
Reputation: 56479
int tableau [] = {nombre};
It doesn't declare an array with nombre size of elements.
It declares an array with 1 item which is initialized to nombre
.
Upvotes: 2