C++动态数组初始化

C++ dynamic array initialisation

本文关键字:初始化 数组 动态 C++      更新时间:2023-10-16

我的一个朋友正在开始他的编程/C++之旅,所以我告诉他要玩循环和数组。

他制作了一个简单的控制台程序来读取整数并计算平均值。

#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;
}

我一直认为C++数组是静态的,如果我想要动态的,我必须选择指针或向量等。

困扰我的是

int nombre;
int affNombre = 1;
int tableau [] = {nombre};

起初我认为,由于nombre没有初始化,默认情况下它被设置为某个非常大的整数,因此他的数组具有非常大的容量。。。但经过一些调试后,我不太确定。

那么这到底是怎么回事呢?

编辑:我知道这是错误的。我知道他应该使用向量。但是这个代码正在运行。输出值有效。我只是想从技术上了解这个东西是如何工作的。

int tableau [] = {nombre};

它不声明元素大小为nombre的数组。

它声明了一个具有1个项的数组,该数组已初始化为nombre

int nombre;
int affNombre = 1;
int tableau [] = {nombre};

这不会创建动态数组;它将指向数组的指针初始化为1。如果你的朋友想学习C++,我鼓励他们利用C++结构(例如vector)。整个程序可以使用C++结构用大约7行C++编写:

#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;
}
int nombre;
int affNombre = 1;
int tableau [] = {nombre};

上面的代码声明了大小为1的"tableau"数组,其值为nombre。

然而,我认为您在使用以下代码时遇到了内存损坏

//Saisi des nombres du tableau
for (int i = 0; i < largeurTab; i++)
{
cout << endl << "Nombre " << affNombre << endl;
cin >> nombre;
tableau [i] = nombre;
affNombre += 1;
}

您有一个大小为1的元素数组表。但您正在循环使用largeurTab,并在tableau中插入那么多元素,但它只能合法地容纳单个元素。所以您实际上遇到了缓冲区溢出。

幸运的是你的程序运行良好。请像其他人已经推荐的那样使用vector,或者动态分配数组。

这里发生的事情是,tableau被视为一个指针,并且您正在写入它所指向的位置。

以下是一篇关于变量如何在内存中布局的文章:
http://www.geeksforgeeks.org/memory-layout-of-c-program/

在文章中,tableau被布置在具有读写访问权限的"initialized data"(仅因为它具有= {nombre};)中,这意味着如果他有多个全局初始化数组(如tableau,比如foobar),他可以通过写入foobar来覆盖tableau中的值而且更糟糕的是,如果您对tableaufoobar使用了足够大的索引,则可能会开始覆盖其他全局索引。

以下是foobar重写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;
}

最后的输出将是tableau[0] = 666,注意我们没有直接写入

这是在Microsoft visual studio中编译的。

下面是一个在Codepad.org上运行的例子,其中moyenne被重写了:http://codepad.org/Y1JMC8V5