多维数组 - malloc 与 new
Multidimensional Arrays - malloc vs new
我想分配二维数组,我正在考虑两种可能性(Arduio 上的 avr-gcc):
甲:
int **arr = new int*[5];
for(int i = 0 ; i < 5 ; i++){
arr[i] = new int[10];
}
乙:
int **arr = malloc(5 * sizeof(int *));
for(int i = 0 ; i < 5 ; i++) {
arr [i] = malloc(10* sizeof(int))
}
A和B有区别吗?编译器会在这两种情况下创建相同的字节码 (arv-gcc) 吗?
A和B基本等价
编译器可能会或可能不会创建相同的代码(顺便说一句,不是字节码)。但通常使用 new
运算符简单地归结为对 malloc
的调用。要找出答案,请使用 gcc -S
编译您的程序并查看汇编输出。
但对于 C++ 程序,您应该更喜欢 new
而不是 malloc
。
在C中,你不能通过new
分配内存,因为没有这样的东西。对于 C++,您可能更喜欢 new
,原因如下:
- 例外(除非您明确添加
(std::nothrow)
)
- 初始化器列表 (C++11 起)
- 更好的安全性,因为它 returns 正确类型的指针(特别不是
void *
)
- 更简洁的语法(但这纯粹是主观的)
有关该问题的更多讨论,请参阅 In what cases do I use malloc and/or new?。
如果你想分配一个 two-dimensional 数组并且最右边的大小在 compile-time 处已知(即它是一个常量表达式 - constexpr
),那么你不需要循环。
C++ 中的新功能
int (*arr)[10] = new int [2][10];
如果你希望它是 pre-set 带零(即像 std::calloc
),那么使用:
int (*arr)[10] = new int [2][10]{0}; // C++11
int (*arr)[10] = new int [2][10](); // C++03
就像由 new[]
分配的任何数组一样,有一个相应的 delete[]
运算符来释放它:
delete[] arr;
C 和 C++ 中的 Malloc
int (*arr)[10] = malloc(5 * sizeof(*arr));
这分配数组,就像arr[5][10]
(仅在索引意义上)。
要在两者中访问其元素,只需使用:
arr[a][b]
要释放它,您基本上可以这样做:
free(arr);
在 C++ 中,您还需要处理转换并可能使用 std
对其进行限定,因此它是 std::malloc
(尤其是如果包含 cstdlib
,如 stdlib.h
header 在 C++ 标准中已被弃用):
const int N = 10;
int (*arr)[N] =
static_cast<int (*)[N]>(std::malloc(5 * sizeof(*arr)));
但我认为你不会喜欢它。
如果您使用的是 C++ 编译器(而 Arduino 草图 是 C++),您可能更喜欢 new
。做一个简单的 int
数组不太可能重要,但我只为 C 环境中 具有 到 运行 的代码保留 C 遗留内容。
现在绝对没有理由存在 C+ 程序员(那种从不全心全意地从 C 过渡到 C++ 的好奇的程序员):-)
我想分配二维数组,我正在考虑两种可能性(Arduio 上的 avr-gcc):
甲:
int **arr = new int*[5];
for(int i = 0 ; i < 5 ; i++){
arr[i] = new int[10];
}
乙:
int **arr = malloc(5 * sizeof(int *));
for(int i = 0 ; i < 5 ; i++) {
arr [i] = malloc(10* sizeof(int))
}
A和B有区别吗?编译器会在这两种情况下创建相同的字节码 (arv-gcc) 吗?
A和B基本等价
编译器可能会或可能不会创建相同的代码(顺便说一句,不是字节码)。但通常使用 new
运算符简单地归结为对 malloc
的调用。要找出答案,请使用 gcc -S
编译您的程序并查看汇编输出。
但对于 C++ 程序,您应该更喜欢 new
而不是 malloc
。
在C中,你不能通过new
分配内存,因为没有这样的东西。对于 C++,您可能更喜欢 new
,原因如下:
- 例外(除非您明确添加
(std::nothrow)
) - 初始化器列表 (C++11 起)
- 更好的安全性,因为它 returns 正确类型的指针(特别不是
void *
) - 更简洁的语法(但这纯粹是主观的)
有关该问题的更多讨论,请参阅 In what cases do I use malloc and/or new?。
如果你想分配一个 two-dimensional 数组并且最右边的大小在 compile-time 处已知(即它是一个常量表达式 - constexpr
),那么你不需要循环。
C++ 中的新功能
int (*arr)[10] = new int [2][10];
如果你希望它是 pre-set 带零(即像 std::calloc
),那么使用:
int (*arr)[10] = new int [2][10]{0}; // C++11
int (*arr)[10] = new int [2][10](); // C++03
就像由 new[]
分配的任何数组一样,有一个相应的 delete[]
运算符来释放它:
delete[] arr;
C 和 C++ 中的 Malloc
int (*arr)[10] = malloc(5 * sizeof(*arr));
这分配数组,就像arr[5][10]
(仅在索引意义上)。
要在两者中访问其元素,只需使用:
arr[a][b]
要释放它,您基本上可以这样做:
free(arr);
在 C++ 中,您还需要处理转换并可能使用 std
对其进行限定,因此它是 std::malloc
(尤其是如果包含 cstdlib
,如 stdlib.h
header 在 C++ 标准中已被弃用):
const int N = 10;
int (*arr)[N] =
static_cast<int (*)[N]>(std::malloc(5 * sizeof(*arr)));
但我认为你不会喜欢它。
如果您使用的是 C++ 编译器(而 Arduino 草图 是 C++),您可能更喜欢 new
。做一个简单的 int
数组不太可能重要,但我只为 C 环境中 具有 到 运行 的代码保留 C 遗留内容。
现在绝对没有理由存在 C+ 程序员(那种从不全心全意地从 C 过渡到 C++ 的好奇的程序员):-)