malloc calloc 等内存分配函数所获得的内存块都来自一个称为 堆(heap)的存储池。
内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏缺陷具有隐蔽性、积累性的特征,比其他内存非法访问错误更难检测。
void *类型的指针可以与任意类型的指针之间进行强制转换,其中包括二级指针(双指针)及以上。
1). sizeof可确定数组的长度.
例如:定义整型数组 a[10] 则数组a的长度为: sizeof(a)/sizeof(a[0])
该表达式更多应用于不知道数组a大小的前提下,即定义时不指明数组长度: int a[ ]={1,2,3,4,5,6,7,...,...}; 此时可快速确定其长度。
因表达式过于繁琐,可用一个宏来表示: #define SIZE (sizeof(a)/sizeof(a[0]))
qsort的原型:
void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *));
qsort函数使用快速排序,排序效率比较高。
其中,base指向需要排序区域的第一个元素,nmemb是要排序的元素的数量,size是每个数组元素的大小,compar是指向比较函数的指针,比较函数需要自行编写,注意比较函数的形参类型为 void *,进行比较时要进行强制转换。比较函数的返回类型为整型(正数、负数或0)。
注意:若返回值小于 0 ,则 p 所指元素排在 q 所指元素前面
若返回值大于 0 ,则 p 所指元素排在 q 所指元素后面
若返回值等于 0 ,则 p 所指元素和 q 所指元素的位置不确定
例如,对一维整型数组进行由小到大排序:
int compare(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
由大到小排序:
int compare(const void *a,const void *b)
{
return *(int *)b-*(int *)a;
}
在一条语句中函数的传递通过栈结构来实现,即先入后出。
#include
int i=1;
void add(int a,int b);
int f(void);
int main()
{
add(f(),f());
return 0;
}
void add(int a,int b)
{
printf("%d %d\n",a,b);
}
int f(void)
{
i++;
return i;
}
在该示例中,函数 f 被调用两次,最终的输出结果为:3 2 证明了其调用过程为从右向左,符合栈的特征(入栈为从左向右)。这一特征不局限于调用同一个函数,本例只调用一个函数是因为......懒。
使用malloc或calloc函数动态分配的内存可能出现过大或者过小的问题,因该内存已存入相关数据,进行整体的转移并不容易,故可使用realloc函数对该内存进行重新分配。
realloc函数的原型:
void *realloc(void *ptr,size_t size);
其中ptr必须指向由malloc或calloc等函数动态分配所产生的内存,size表示新内存的大小。
realloc函数对内存的重新分配是在原内存的基础上直接进行扩大或缩减,不会影响到数据在原内存中的存储,即不需要移动数据。当无法在原内存的基础上直接扩大时,realloc函数会在别处分配新的内存块,之后将原内存中的数据复制到新内存中。因此,当内存块移动到其他地方后,要及时释放原内存,避免内存泄漏的发生。
#include
#include
#define N 10
int main()
{
int *base,*p;
base=(int *)(malloc(N*sizeof(int)));
p=base;
int i;
for(i=0;i