在 C++ 中的函数内更改二维数组的值
Altering values of a 2D array inside a function in C++
在 C++ 中初始化和更改使用 int**
声明的二维整数数组的正确语法是什么?
我正在使用下面的代码,但由于内存在函数退出时被取消分配,我得到了意想不到的行为,这当然是它的本意。
但是,这怎么能用 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);
}
正如 spug 所说,内存并没有被释放,你只是丢失了指针。您需要通过引用传递它:
void Init_2D_Array(int** & foo, int x_size, int y_size)
我建议永远不要在 C++ 中使用多维数组,除非您真的需要指向指针的指针。一种更简单、更安全的方法是围绕大小为 x*y
的一维数组创建包装器 class,然后定义函数或运算符,使您能够通过指定 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];
}
};
此解决方案还有一个额外的好处,即通过线性和紧密打包的方式存储内容,对缓存更加友好。
如 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;
}
首先,对于二维数组或任何其他多维数组,最好使用一维缓冲区作为存储,并将项目作为 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;
}
在 C++ 中初始化和更改使用 int**
声明的二维整数数组的正确语法是什么?
我正在使用下面的代码,但由于内存在函数退出时被取消分配,我得到了意想不到的行为,这当然是它的本意。
但是,这怎么能用 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);
}
正如 spug 所说,内存并没有被释放,你只是丢失了指针。您需要通过引用传递它:
void Init_2D_Array(int** & foo, int x_size, int y_size)
我建议永远不要在 C++ 中使用多维数组,除非您真的需要指向指针的指针。一种更简单、更安全的方法是围绕大小为 x*y
的一维数组创建包装器 class,然后定义函数或运算符,使您能够通过指定 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];
}
};
此解决方案还有一个额外的好处,即通过线性和紧密打包的方式存储内容,对缓存更加友好。
如 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;
}
首先,对于二维数组或任何其他多维数组,最好使用一维缓冲区作为存储,并将项目作为 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;
}