云计算百科
云计算领域专业知识百科平台

C语言---内存空间相关函数(malloc函数、free函数、realloc函数、calloc函数)、函数指针、指针的指针

一、与内存空间相关的函数

   1、malloc 函数

        一般形式:malloc( n * sizeof(数据类型))。其中 n 为该空间的元素个数;n * sizeof(数据类型) 为该空间所占字节的大小。

        malloc 函数用来申请空间,并将该空间的首地址传给用户。使用该函数时,需要包含头文件:#include<stdlib.h>

eg1. 在内存中开辟一段空间,存放字符型指针数组s的内容 

int main(void)
{
const char *s = "Hello World!";
char *p = malloc(strlen(s) + 1);
strcpy(p, s);
puts(p);
free(p);
p = NULL;//防止p成为野指针
}

   2、free 函数

        free 函数用来销毁空间。free 函数遇到空指针不会出错,其需满足以下三点要求:

        (1) 不能将以销毁的空间连续再次销毁;

        (2) 申请空间的指针不能被修改,否则会引起销毁错误;

        (3) 程序代码中的申请空间与销毁成对出现,遵循 "有借有还,再借不难" 原则。

   3、realloc 函数

        一般形式:realloc ( void *p, size_t size)。其中 p 为万能指针,是原空间的首地址;size 是新开空间的大小,计算方式为 “n*sizeof(数据类型)” ,n 为所需元素个数。

        realloc 函数用来重新分配(扩容)。将原空间的内容复制到新空间的同时,将原空间释放。为防止野指针的出现,调用该函数的方式为:(参数部分自己填入)

char *p;p = realloc(参数);

eg2. 在 eg1 的基础上,对申请空间进行扩容操作,将字符型指针数组t中的内容连接到p后面

int main(void)
{
const char *s = "Hello World!";

char *p = malloc(strlen(s) + 1);
strcpy(p, s);
//扩容
const char *t = "China";
p = realloc(p, strlen(p) + strlen(t) + 1);
strcat(p, t);
puts(p);
free(p);
p = NULL;

return 0;
}

   4、calloc 函数

        一般形式:calloc (n, sizeof(数据类型) )。其中 n 为申请元素个数;sizeof(数据类型) 为每个元素所占字节。

        calloc 函数也用来申请空间,只是与 malloc 函数的表达形式不同。例如:申请大小为 n*sizeof(int) 字节的内存空间,两种函数的表达式分别如下所示:

char *p = malloc( n * sizeof(int));char *p = calloc( n, sizeof(int));

eg3. 先申请10个整型大小的空间来存放 “1,2,3,4,5,6,7,8,9,10”,再对空间进行扩容操作,存放1到20的整数 

void printArray(int *a, int len)
{
int i;
for(i = 0;i < len;++i)
{
printf("%d ", a[i]);
}
puts("");
}

int main(void)
{
int n = 10;
//int *p = malloc(n * sizeof(int));
int *p = calloc(n, sizeof(int));
//存放1到10
int i;
for(i = 0;i < n;++i)
{
*(p + i) = i + 1;
}
//扩容存放1到20
int m = 20;
p = realloc(p, m * sizeof(int));
for(i = 10;i < m;++i)
{
p[i] = i + 1;
}
printArray(p, m);
free(p);

return 0;
}

二、函数指针

        一般形式:返回值类型 (*指针名)(参数列表)。其中指针类型为去掉指针名的剩余部分。     

        函数的指针用来存储函数的入口地址(函数名),通过指针可以间接调用函数。为防止野指针的出现,需要对指针进行初始化,即 “= NULL” 。

eg4. 定义add函数,运用函数指针实现add函数的间接调用

int add(int a, int b)
{
return a + b;
}
int main(void)
{
int (*p)(int , int ) = NULL;//*p的圆括号不能省略
p = add;//指针变量p指向函数入口地址
printf("%d\\n", p(10, 20));//调用add函数
return 0;
}

        使用函数指针实现回调函数功能,即:将函数指针作为参数传递给其他函数。

eg5. 编写排序函数,并在最后的主函数中,选择排序方式(pow2:以平方大小排序; fn:以元素本身大小排序),pow2 和 fn 函数称为回调函数

int pow2(int n)//以元素0平方大小排序
{
return n * n;
}

int fn(int n)//以元素本身大小排序
{
return n;
}

void sort(int *a, int len, int (*pfn)(int))
{
int i, j;
for(i = 0;i < len – 1;++i)
{
for(j = i + 1;j < len;++j)
{
if(pfn(a[i]) > pfn(a[j]))
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
}
int main(void)
{
int a[] = {-1,2,-3,4,-5,6,-7,8,-9,0};
int len = sizeof(a) / sizeof(*a);
sort(a, len, pow2);
printArray(a, len);
return 0;
}

三、指针的指针

   1、概念        

        指针的指针也称为二级指针,即指向指针的指针。指针数组作为函数参数,形参是指向指针的指针。

        对于下图中的代码,程序会在第308、309行崩掉,显示越界访问,只是值传递

修改地方:(1) 第一行的“ *p ” 改为 “ **p ” ;

                  (2) 第三行的 “ p = ” 改为 ” *p = “;

                  (3) 第九行的 getMem(s) 改为 “ getMem(&s) ”;

            修改后的代码为:

void getMem(char **p)
{
*p = malloc(100);
}
int main(void)
{
char *s;
getMem(&s);
strcpy(s, "Hello");
puts(s);
return 0;
}

   2、例题

eg1. 运用指针的指针选出字符数组中的最大值

char *maxStrings(char **p, int len)
{
char *max;
max = p[0];
int i;
for(i = 1;i < len;++i)
{
if(strcmp(max, p[i]) < 0)
{
max = p[i];
}
}
return max;
}

eg2.运用指针的指针进行字符数组的逆序

void reverseStrings(char **p, int len)
{
int i;
for(i = 0;i < len / 2;++i)
{
char *t;
t = p[i];
p[i] = p[len – i – 1];
p[len – i – 1] = t;
}
}

eg3. 运用指针的指针进行字符数组的交换

void swap(char **a, char **b)
{
char *t;
t = *a;
*a = *b;
*b = t;
}

eg4. 运用指针的指针进行字符数组的排序

void sortStrings(char **p, int len)
{
int i, j;
for(i = 0;i < len – 1;++i)
{
for(j = i + 1;j < len;++j)
{
if(strcmp(p[i], p[j]) > 0)
{
swap(p + i, p + j);
}
}
}
}

【END】

赞(0)
未经允许不得转载:网硕互联帮助中心 » C语言---内存空间相关函数(malloc函数、free函数、realloc函数、calloc函数)、函数指针、指针的指针
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!