打印在类中创建的数组
Printing arrays created in a class
我正在尝试打印在类初始值设定项中创建的数组。我尝试了很多方法,但我的发现是,我必须使用指针来解决这个问题。代码:
#include <iostream>
// arr.h
class Arr
{
private:
const int sizeVertical;
const int sizeHorizontal;
int *ptr;
public:
Arr(int sizeVertical, int sizeHorizontal);
void Init();
void Print();
};
// arr.cpp
Arr::Arr(int _sizeVertical, int _sizeHorizontal)
: sizeVertical(_sizeVertical),
sizeHorizontal(_sizeHorizontal)
{
int arr2d[sizeVertical][sizeHorizontal];
ptr = &arr2d[0][0];
}
void Arr::Init()
{
for(int i=0; i<sizeVertical; i++)
{
for(int j=0; j<sizeHorizontal; j++)
{
*(ptr + i * sizeHorizontal + j) = i+j;
}
}
}
void Arr::Print()
{
for(int i=0; i<sizeVertical; i++)
{
for(int j=0; j<sizeHorizontal; j++)
{
std::cout<<*(ptr + i * sizeHorizontal + j)<<std::endl;
}
}
}
// main.cpp
int main()
{
Arr test(4,3);
test.Init();
test.Print();
}
在我定义数组的方法(Init)中,我也可以用与方法(print)中相同的方式打印数组。但是,当尝试用不同的方法打印数组时,输出看起来非常奇怪。输出:
0
22025
955388640
32767
10
0
-1247975061
32668
1
3
-1549041632
22025
有什么想法吗?
创建本地数组,并将其第一个元素的地址分配给指针。但当构造函数完成时,数组就不见了,所以存储在指针中的地址已经无效。
在Undefined Behavior中访问此地址,这意味着当您运行该代码时,任何事情都可能发生。
处理此问题的最佳方法是使用std::vector<std::vector<int>>
,如评论中所建议的:
#include <vector>
class Arr
{
private:
const int sizeVertical;
const int sizeHorizontal;
std::vector<std::vector<int>> arr2d;
public:
Arr(int sizeVertical, int sizeHorizontal);
void Init();
void Print();
};
// arr.cpp
Arr::Arr(int _sizeVertical, int _sizeHorizontal)
: sizeVertical(_sizeVertical),
sizeHorizontal(_sizeHorizontal),
arr2d(_sizeVertical, std::vector<int>(_sizeHorizontal))
{
}
CCD_ 2可以使用CCD_。
请注意,您不再需要sizeVertical
和sizeHorizontal
,您可以使用arr2d.size()
和arr2d[0].size()
:
for(int i=0; i<arr2d.size(); i++)
{
for(int j=0; j<arr2d[0].size(); j++)
{
}
}
就我个人而言,我认为命名常数比这个更可读,但它们要求你永远不要改变向量的大小。正如注释中所指出的,您也可以在需要的函数中本地创建这样的常量。
您也可以使用动态内存分配,但我不建议这样做。很难正确管理内存,你必须遵循三/五规则
在构造函数中使用自动变量arr2d
的地址初始化指向intptr
的指针。在堆栈中分配的自动变量,一旦离开分配它们的代码范围{ ... }
,就会自动销毁。因此,在您离开构造函数之后,ptr
中的地址将不再有效,因为arr2d
已被销毁。您可以在构造函数中使用动态内存分配
Arr::Arr(int _sizeVertical, int _sizeHorizontal)
: sizeVertical(_sizeVertical),
sizeHorizontal(_sizeHorizontal)
{
ptr = new int[sizeVertical * sizeHorizontal];
}
不要忘记在析构函数中释放它:
Arr::~Arr(void)
{
delete[] ptr;
}
问题是您的数组已被解除分配。
Arr::Arr(int _sizeVertical, int _sizeHorizontal)
: sizeVertical(_sizeVertical),
sizeHorizontal(_sizeHorizontal)
{
int arr2d[sizeVertical][sizeHorizontal]; // arr2d allocated.
ptr = &arr2d[0][0];
} // arr2d dies here
相反,正如πάΓτα正确地提出的那样ῥεῖ,您可以使用std::vector< std::vector<int> >
。如果你不想这样做,你可以使用动态内存,尽管我不推荐它
Arr::Arr(int _sizeVertical, int _sizeHorizontal)
: sizeVertical(_sizeVertical),
sizeHorizontal(_sizeHorizontal)
{
ptr = new int[sizeVertical * sizeHorizontal];
}
确保通过在析构函数中设置delete
来释放分配给它的动态内存。
Arr::~Arr()
{
delete[] ptr;
}
这被称为RAII模式,它保证了去初始化。
编辑:
如果您不打算更改数组的维度,那么我强烈建议您使用std::array
。
#include <iostream>
#include <array>
template<int sizeVertical, int sizeHorizontal>
class Arr
{
private:
std::array<std::array<int, sizeHorizontal>, sizeVertical> arr;
public:
Arr() { }
void Init() {
for (int i = 0; i < sizeVertical; i++) {
for (int j = 0; j < sizeHorizontal; j++) {
arr[i][j] = i + j;
}
}
}
void Print() {
for (int i = 0; i < sizeVertical; i++) {
for (int j = 0; j < sizeHorizontal; j++) {
std::cout << arr[i][j] << " ";
}
std::cout << "n";
}
}
};
int main()
{
Arr<10, 2> arr;
arr.Init();
arr.Print();
}
- 在c++中为double类型的数组创建一个unique_ptr
- 如何从预定义的数组创建某些元素数组
- 基于数组的列表 - 动态数组创建时出错
- 从 UTF-8 字节数组创建字符串?
- 是否可以在并行区域中为共享 2D 数组创建选定元素的线程本地副本?(共享,私有,障碍:OPenMP)
- C++ 从名称数组创建对象
- 从数组创建 Mat 时,'cv::Mat' 和 'int' 类型不兼容
- 从 std::数组创建十六进制代表
- 在 C++ 结构内声明的数组 A[1] 创建多个实例
- 为多维数组创建内存空间
- 如何使用任何类型的数组创建模板类并为其设置值?
- 从字符串数组创建一个字符数组
- 是否可以在不为该数组创建变量的情况下将数组作为参数传递到函数中?
- 使用类定义数组创建C++类
- 使用具有唯一随机数的结构数组创建多个对象
- 谷歌测试:无法从字符数组创建字符串
- 从 1D 数组创建 2D 数组
- 无法通过一个单向链表数组创建邻接列表
- 如何使用数组创建标准::函数
- 在C++中,返回从本地字符数组创建的字符串是否会导致内存泄漏或未定义的行为