C ++中用于初始化和更改使用int**
声明的2D整数数组的正确语法是什么?
我正在使用下面的代码,但由于在函数退出时取消分配内存,我得到了意外的行为,这当然是它的意思。
但是,如何在C ++中巧妙地完成这项工作?我知道其他人也遇到过类似的问题,但Is passing pointer argument, pass by value in C++?等问题过于笼统。
void Insert_into_2D_Array(int** foo, int x_pos, int y_pos, int x_size, int y_size)
{
int insert_value = 10;
if (x_pos < x_size && y_pos < y_size) {
foo[x_pos][y_pos] = insert_value; // insert_value lost post func exit?
}
}
void Init_2D_Array(int** foo, int x_size, int y_size)
{
foo = new int*[x_size]; // new alloc mem lost post func exit ?
for (int i=0;i<x_size;i++)
{
foo[i] = new int[y_size]; // new alloc mem lost post func exit
}
}
int main(int agc, char** argv)
{
int** foo;
int x_size=10, y_size=10;
Init_2D_Array(foo, x_size, y_size);
Insert_into_2D_Array(foo, 3,3, x_size, y_size);
}
答案 0 :(得分:1)
就像spug所说,内存没有被释放,你只是失去了指针。您需要通过引用传递它:
void Init_2D_Array(int** & foo, int x_size, int y_size)
我建议不要在C ++中使用多维数组,除非确实需要指针指针。一种更简单,更安全的方法是围绕大小为x*y
的一维数组创建一个包装类,然后定义函数或运算符,使您能够通过指定x
和y
来访问基础元素坐标。
class Array2D
{
private:
int* m_array;
int m_sizeX;
int m_sizeY;
public:
Array2D(int sizeX, int sizeY) : m_sizeX(sizeX), m_sizeY(sizeY)
{
m_array = new int[sizeX*sizeY];
}
~Array2D()
{
delete[] m_array;
}
int & at(int x, int y)
{
return m_array[y*sizeX + x];
}
};
此解决方案还有一个额外的好处,即通过线性和紧凑地存储内容来提高缓存友好性。
答案 1 :(得分:1)
作为underscore_d建议,正确的方法是使用std :: vector并传递引用。
但如果您仍想在代码中使用指针,
这里
if (x_pos < x_size && y_pos < y_size) {
foo[pos] = insert_value; // insert_value lost post func exit
}
对我有用的代码是:
void Insert_into_2D_Array(int** foo, int x_pos, int y_pos, int x_size, int y_size)
{
int insert_value = 10000;
if (x_pos < x_size && y_pos < y_size) {
(foo)[x_pos][y_pos] = insert_value; // insert_value lost post func exit
}
}
void Init_2D_Array(int*** foo, int x_size, int y_size)
{
*foo = new int*[x_size]; // new alloc mem lost post func exit
for (int i=0;i<x_size;i++)
{
(*foo)[i] = new int[y_size]; // new alloc mem lost post func exit
}
}
void main(){
int** foo = NULL;
int x_size=10, y_size=10;
Init_2D_Array(&foo, x_size, y_size);
Insert_into_2D_Array(foo, 3,3, x_size, y_size);
cout<<"############# "<<foo[3][3]<<endl;
}
答案 2 :(得分:1)
首先,对于2D数组或任何其他多维数组,最好使用一维缓冲区作为存储,并将项目称为y * width + x;
但是对于你的特殊情况,如果你真的想像你那样使用它就会遇到一些问题。 这里有固定的代码。首先,在init函数中,我们不会返回新分配的指针。您传递给函数和地址,您将返回传递给函数的相同地址。新分配的地址将丢失。
void Insert_into_2D_Array(int** foo, int x_pos, int y_pos, int x_size, int y_size)
{
int insert_value = 10;
if (x_pos < x_size && y_pos < y_size) {
foo[x_pos][y_pos] = insert_value; // insert_value lost post func exit
}
}
int** Init_2D_Array(int x_size, int y_size)
{
int** foo = new int*[x_size]; // new alloc mem lost post func exit
for (int i = 0; i<x_size; i++)
{
foo[i] = new int[y_size]; // new alloc mem lost post func exit
}
return foo;
}
int main()
{
int** foo;
int x_size = 10, y_size = 10;
foo = Init_2D_Array(x_size, y_size);
Insert_into_2D_Array(foo, 3, 3, x_size, y_size);
return 0;
}