Dave
Dave

Reputation: 2984

C++ dynamic array initialisation

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

Answers (4)

tamato
tamato

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

Zac Howland
Zac Howland

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

mshriv
mshriv

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

masoud
masoud

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

Related Questions