是一样的
char* s1[size];
要
char** s2 = malloc(size * sizeof(char*));
它们有什么区别?
答案 0 :(得分:2)
理论上,*arr[]
和**arr
是不同的。例如:
char *arr[size]; //case 1
此处arr
是一个大小为size
的数组,其元素的类型为char*
然而,
char **arr; //case2
此处arr
本身就是指向char*
注意:在案例1 数组
arr
降级为指针成为char**
类型,但不可能反过来ie , case 2 中的指针不能成为数组。
答案 1 :(得分:-1)
差异很小:
s1
不是左值,因此无法修改(例如使用赋值或增量运算符)。因此,它类似于char** const s1
类型,它也不允许修改(但在这种情况下,这是由const
修饰符引起的。)在数组地址上使用的运算符&
将返回数组的地址(即第一个元素的地址)。当&
将用于变量时,它将返回其地址:
assert((void*)&s1 == (void*)s1);
assert((void*)&s2 != (void*)s2);
sizeof()
将返回数组大小,而指针上使用的sizeof()
将返回指针大小 - 通常它与sizeof(void*)
相同,但C标准确实如此不需要这个(见下面的评论):
assert(sizeof(s1) == size * sizeof(char*));
assert(sizeof(s1) == size * sizeof(s1[0])); // this is the same
assert(sizeof(s2) == sizeof(void*)); // on some platforms this may fail
当然显而易见的一个 - s1
在堆栈上分配,s2
在堆上。由于此s1
将在执行离开当前范围时自动销毁,s2
需要调用free
来释放内存。
更新:这是检查上述断言的示例代码:
#include <assert.h>
#include <stdlib.h>
int main()
{
const int size = 22;
char* s1[size];
char** s2 = (char**)malloc(size * sizeof(char*));
assert((void*)&s1 == (void*)s1);
assert((void*)&s2 != (void*)s2);
assert(sizeof(s1) == size * sizeof(char*));
assert(sizeof(s1) == size * sizeof(s1[0])); // this is the same
assert(sizeof(s2) == sizeof(void*)); // on some platforms this may fail
free(s2);
// Attempts to modify value
char** const s3 = s1;
++s2;
//++s1; // compilation error - lvalue required as increment operand
//++s3; // compilation error - increment of read-only variable ‘s3’
return 0;
}
答案 2 :(得分:-1)
char* s1[size];
是在堆栈上分配的char
类型的指针数组。
char** s2 = malloc(size * sizeof(char*));
是一个类型为char **
的指针,它在堆栈上分配,但指向堆上分配的char *
类型的动态指针数组。
两者在范围和数组与指针之间的通常差异方面存在差异。
答案 3 :(得分:-1)
s1
是一个数组,s2
是一个指针。 s2
指向malloc
ed数组的第一个元素。
数组s1
具有自动存储持续时间,而s2
指向的数组具有动态存储持续时间。
此外,在C89中char* s1[size];
仅在size
是常量表达式时有效,因为C89不支持可变长度数组。