【发布时间】:2011-10-05 13:51:03
【问题描述】:
声明数组有什么区别:
int arr[100];
和
int* arr=(int*)malloc(sizeof(int)*100);
哪一个更受欢迎?这其中是否涉及堆和堆栈内存之类的东西?
【问题讨论】:
-
@JSBangs :是的,堆栈变量与堆变量正好回答了我的问题。谢谢你把我带到那里。
标签: c heap-memory stack-memory
声明数组有什么区别:
int arr[100];
和
int* arr=(int*)malloc(sizeof(int)*100);
哪一个更受欢迎?这其中是否涉及堆和堆栈内存之类的东西?
【问题讨论】:
标签: c heap-memory stack-memory
我建议去书店买一本 Kernighan 和 Ritchie 的C 编程语言,还可以选择买一本 Harbison & Steele 的C: A Reference Manual.
第一种情况给你一个 100 个整数的数组,分配在堆栈上。后一种情况给你一个指向 int 的指针,它的地址是分配在堆上的缓冲区的地址,其大小足以容纳 100 个 int。
C 语言本质上是一种与硬件无关的汇编语言。指针和数组之间的区别是故意模糊的,因为数组引用表示法是指针算术的语法糖。这个:
int foo( int a )
{
int x[100] = load_X() ;
int y = x[ a ] ;
return y ;
}
等同于
int foo( int a )
{
int *x = load_X() ;
int y = *( x + a ) ;
// note that the use of sizeof() isn't required. For the pointer carries around
// an implicit increment size (the size of the object to which it points). The above
// is equivalent to
//
// int y = *(int*)((char*)x + (a*sizeof(*x)) ) ;
}
此外,编译器将(或应该)抱怨类型不匹配,给定函数foo():
public void foo( int a[] )
{
...
}
调用:
int *p = malloc(...) ;
foo(p) ;
应该导致编译器抱怨类型不匹配。
【讨论】:
第一个将arr 声明为位于堆栈上的int[100] 类型的数组。在某些情况下arr 会衰减为int * 类型的指针,但这并不能使其成为指针。为了进一步强调它不是指针,sizeof(arr) 将产生 sizeof(int) * 100,而不是地址的大小。
第二个声明了一个int * 类型的指针,并将其初始化为malloc 返回的指针,这实际上是在堆上分配内存。请注意,在这种情况下,arr 不是数组 - 您可以使用数组表示法来偏移和取消引用指针,但这不会使其成为数组。
【讨论】:
前者分配一个大小为100的自动数组,一旦超出范围就会自动释放。
后者在空闲存储中为 100 个ints 分配空间,并返回一个指向内存块开头的指针。在指针上调用free() 之前,它将一直保持分配状态。
如果您只需要与当前范围一样长的内存,那么前者更容易使用(假设它不是太大。)否则,后一种选择是采用的方法。
【讨论】: