我正在尝试打印在类初始值设定项中创建的数组。我尝试了多种方法,但是我的发现是我必须使用指针解决该问题。代码:
#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
有什么想法吗?
答案 0 :(得分:2)
您创建本地数组,并将其第一个元素的地址分配给指针。但是当构造函数完成时,数组消失了,因此指针中存储的地址已经无效。
以“不确定行为”访问此地址,这意味着在运行该代码时可能发生任何事情。
处理此问题的最佳方法是使用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))
{
}
Init
可以使用[][]
而不是指针算术来方便访问。
请注意,您不再需要sizeVertical
和sizeHorizontal
,可以改用arr2d.size()
和arr2d[0].size()
:
for(int i=0; i<arr2d.size(); i++)
{
for(int j=0; j<arr2d[0].size(); j++)
{
}
}
就我个人而言,我认为命名常量比这更易读,但是它们将要求您永远不要更改向量的大小。如注释中所述,您还可以在需要它们的函数中本地创建此类常量。
您也可以使用动态内存分配,但是我不建议这样做。正确管理内存很困难,您将必须遵循Rule of Three/Five
答案 1 :(得分:0)
问题是您的阵列已被释放。
for(int n = 0; n < person.length; n++)
{
if(person[n].getSecId().contains("98"))
{
System.out.println(person[n].toString());s
//delete this object from person array
}
}
相反,如πάντα ῥεῖ所正确建议的那样,您可以使用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
这被称为 RAII模式,它可以确保取消初始化。
修改:
如果您不打算更改数组的尺寸,那么我强烈建议您使用Arr::~Arr()
{
delete[] ptr;
}
。
std::array
答案 2 :(得分:0)
您可以使用构造函数中自动变量ptr
的地址初始化指向整数arr2d
的指针。自动变量在堆栈中分配,并且在离开代码作用域{ ... }
的位置后自动销毁。因此,离开构造函数后,ptr
中的地址不再有效,因为arr2d
被破坏了。您可以在构造函数中使用动态内存分配
Arr::Arr(int _sizeVertical, int _sizeHorizontal)
: sizeVertical(_sizeVertical),
sizeHorizontal(_sizeHorizontal)
{
ptr = new int[sizeVertical * sizeHorizontal];
}
别忘了在析构函数中释放它:
Arr::~Arr(void)
{
delete[] ptr;
}