动态创建二维数组的函数
A function which dynamically creates a 2d array
我想在一个单独的函数中创建一个动态二维数组。数组的大小将在运行时确定。
直接传递一个数组:
void foo(int **arr,int width,int height)
{
arr=new int*[width];
for(int i=0;i<height;i++)
{
arr[i]=new int[height];
}
//fill...
}
...
int** array;
foo(array)
好像不行
通过指针传递数组
void foo(int ***arr,int width,int height)
{
*arr=new int*[width];
for(int i=0;i<height;i++)
{
*arr[i]=new int[height];
}
//fill...
}
...
int **array;
foo(&array)
似乎也不起作用
我该怎么做?
我认为你的"problem"是由于忽略了operator precedence
造成的
您发布的第二个代码似乎有错误:
*arr[i]=new int[height];
应该是
(*arr)[i]=new int[height];
此外,正如其他人指出的那样,使用 raw 指针有时可能非常邪恶(就像在您的示例中 Pointer to Pointer to Pointer), 原始指针也可能导致 内存泄漏 、 悬垂指针 、 等 问题。使用 "more practical" 之类的 std::vector
或其他一些 STL 容器。
(注意:术语 "STL",我指的是基于 STL 的标准库的一部分)
一般来说,多维数组不应该,永远不会这样创建。您应该使用包含在提供行、列、table 等对象中的单个数组。使用 operator()
函数进行访问。
你也不应该,永远不要使用原始指针(除非在奇怪的、情有可原的情况下)这就是我使用STL的原因std::vector
class 来实现你的代码。
class array_2d {
public:
array_2d(size_t width, size_t height) :
width(width),
height(height),
_array(width * height)
{}
int & operator()(size_t x, size_t y) {
return _array[y * width + x];
}
const int & operator()(size_t x, size_t y) const {
return _array[y * width + x];
}
std::pair<size_t, size_t> get_size() const {
return std::make_pair<size_t, size_t>(width, height);
}
private:
size_t width, height;
std::vector<int> _array;
};
int main() {
array_2d my_array(5,5);
my_array(3,3) = 7;
std::cout << my_array(3,3) << std::endl;
return 0;
}
====
7
有很多我没有包括的东西(如果你将其实现为原始指针,代码会复杂得多)但这是编写二维(或更多维度,如果你需要的话)数组。
假设您必须以这种方式创建二维数组(使用 int**
)。
而不是尝试传递指针,return 表示二维数组的值。
其次,您的代码有一个错误,您在 height
上循环,而您应该在 width
上循环。如果 height > width
.
,您的代码将进入未定义的行为
第三,我不知道你的意思是width
是第一维度还是height
是第一维度,所以假设你写的就是你的意思,即width
是第一个维度,height
是内部维度。
int **foo(int width, int height)
{
int **arr = new int*[width];
for(int i=0; i<width; i++)
arr[i]=new int[height];
return arr;
}
//....
int width = 10, height = 10;
int** array = foo(width, height);
那你就得写代码删除分配的数据了:
for (int i = 0; i < width; ++i)
delete [] array [i];
delete [] array;
现在说了上面的内容,并且上面的内容应该可以工作,找到了一个更优化的版本 here,其中数据是一个连续的块,而不是单独分配的块。这减少了需要调用 new[]
和 delete []
的次数。
我想在一个单独的函数中创建一个动态二维数组。数组的大小将在运行时确定。
直接传递一个数组:
void foo(int **arr,int width,int height)
{
arr=new int*[width];
for(int i=0;i<height;i++)
{
arr[i]=new int[height];
}
//fill...
}
...
int** array;
foo(array)
好像不行
通过指针传递数组
void foo(int ***arr,int width,int height)
{
*arr=new int*[width];
for(int i=0;i<height;i++)
{
*arr[i]=new int[height];
}
//fill...
}
...
int **array;
foo(&array)
似乎也不起作用
我该怎么做?
我认为你的"problem"是由于忽略了operator precedence
造成的您发布的第二个代码似乎有错误:
*arr[i]=new int[height];
应该是
(*arr)[i]=new int[height];
此外,正如其他人指出的那样,使用 raw 指针有时可能非常邪恶(就像在您的示例中 Pointer to Pointer to Pointer), 原始指针也可能导致 内存泄漏 、 悬垂指针 、 等 问题。使用 "more practical" 之类的 std::vector
或其他一些 STL 容器。
(注意:术语 "STL",我指的是基于 STL 的标准库的一部分)
一般来说,多维数组不应该,永远不会这样创建。您应该使用包含在提供行、列、table 等对象中的单个数组。使用 operator()
函数进行访问。
你也不应该,永远不要使用原始指针(除非在奇怪的、情有可原的情况下)这就是我使用STL的原因std::vector
class 来实现你的代码。
class array_2d {
public:
array_2d(size_t width, size_t height) :
width(width),
height(height),
_array(width * height)
{}
int & operator()(size_t x, size_t y) {
return _array[y * width + x];
}
const int & operator()(size_t x, size_t y) const {
return _array[y * width + x];
}
std::pair<size_t, size_t> get_size() const {
return std::make_pair<size_t, size_t>(width, height);
}
private:
size_t width, height;
std::vector<int> _array;
};
int main() {
array_2d my_array(5,5);
my_array(3,3) = 7;
std::cout << my_array(3,3) << std::endl;
return 0;
}
====
7
有很多我没有包括的东西(如果你将其实现为原始指针,代码会复杂得多)但这是编写二维(或更多维度,如果你需要的话)数组。
假设您必须以这种方式创建二维数组(使用 int**
)。
而不是尝试传递指针,return 表示二维数组的值。
其次,您的代码有一个错误,您在 height
上循环,而您应该在 width
上循环。如果 height > width
.
第三,我不知道你的意思是width
是第一维度还是height
是第一维度,所以假设你写的就是你的意思,即width
是第一个维度,height
是内部维度。
int **foo(int width, int height)
{
int **arr = new int*[width];
for(int i=0; i<width; i++)
arr[i]=new int[height];
return arr;
}
//....
int width = 10, height = 10;
int** array = foo(width, height);
那你就得写代码删除分配的数据了:
for (int i = 0; i < width; ++i)
delete [] array [i];
delete [] array;
现在说了上面的内容,并且上面的内容应该可以工作,找到了一个更优化的版本 here,其中数据是一个连续的块,而不是单独分配的块。这减少了需要调用 new[]
和 delete []
的次数。