C++动态数组初始化
C++ dynamic array initialisation
我的一个朋友正在开始他的编程/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
中的值而且更糟糕的是,如果您对tableau
或foobar
使用了足够大的索引,则可能会开始覆盖其他全局索引。
以下是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
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在函数内部的声明中初始化数组,并在外部使用它
- 为什么用结构初始化数组需要指定结构名称
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- C++使用另一个数组和新值初始化数组
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 在 constexpr 构造函数中初始化数组是否合法?
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 在构造函数中初始化数组
- 是否可以使用函数返回的值初始化数组
- 使用宏使用额外元素初始化数组
- 在循环中显示不同值的初始化数组
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- 使用可变模板列表初始化数组,并放置new
- 使用函数从 Visual Studio 2017 中的 main 创建和初始化数组
- 使用 c++ 中的函数初始化数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- C++ 使用变量而不是常量表达式初始化数组
- 在初始化列表中初始化数组的更好方法
- 在可变参数模板类中初始化数组