malloc & 指针

1、指针的内存分配

(1)指针定义时不会被分配内存,如int *p;,如果指针没有初始化,会随机分配地址。
(2)指针初始化时,需要给其分配一个地址,如int *p = NULL;int *p = &i;
(3)指针分配内存使用malloc,位于堆区,用完需要free

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char** argv)
{
    int i = 1;       //全局变量分配内存在全局区
    int *p = &i;     //p指针指向i的地址
    int *q = NULL;
	printf("p(%p %d) i(%p %d)\n\n", p, *p, &i, i);
	
	*p = 2;          //改变p所指向地址的值,即改变了全局区的值
	printf("p(%p %d) i(%p %d)\n\n", p, *p, &i, i);

	p = (int *)malloc(sizeof(p));    //分配一块堆区,并把地址赋给p
	printf("p(%p %d) i(%p %d)\n\n", p, *p, &i, i);
	
    *p = 10;                         //改变堆区的内容
	printf("p(%p %d) i(%p %d)\n\n", p, *p, &i, i);                  

	q = p;          //q和p都指向堆区
	free(p);        //**释放堆区(值被清空),p仍指向堆区**
	printf("p(%p %d) q(%p %d)\n\n", p, *p, q, *q);
	
	p = NULL;	    //p为空指针,q仍指向堆区
	printf("p(%p) q(%p)\n\n", p,  q);
	return 0;
}

执行结果:

p(0x7ffffc0473fc 1) i(0x7ffffc0473fc 1)       //p指向i的地址,故打印一样

p(0x7ffffc0473fc 2) i(0x7ffffc0473fc 2)       //全局区被改变了,故p和i均改变

p(0x1f47e80 0) i(0x7ffffc0473fc 2)            //i仍为全局区,p指向堆区

p(0x1f47e80 10) i(0x7ffffc0473fc 2)           //堆区内容被p 改变,值改变

p(0x1f47e80 0) q(0x1f47e80 0)                 //堆区被free

p((nil)) q(0x1f47e80)                         //p为NULL,q仍指向堆区

2、结构体指针的内存分配

#include <stdio.h>
#include <stdlib.h>
 
typedef struct example
{
	int *a;
	int b;
}example_t;

int main(int argc, char** argv)
{
    int *p;
    int i = 1;
	example_t *exam;
	printf("exam(%p %p) p(%p %p)\n\n", &exam, exam, &p, p);   //exam和p都是(结构体)指针变量,&p为全局区指针变量的地址,p为指针变量的值
	exam = (example_t *)malloc(sizeof(example_t));           //堆区分配空间,并赋值给exam
	if(NULL == exam)
	{
		printf("%s\n", "exam malloc failed");
		return -1;
	}
    printf("exam(%p) a(%p %p) b(%p %d)\n\n", exam, &exam->a, exam->a, &exam->b, exam->b);
    //结构体指针成员:指针变量a的地址存在,但其值为NULL;变量b的地址存在,其值未初始化为随机
    
    exam->b = i;  //将全局区i 的值拷贝给堆区b,后操作b,不会影响i

	exam->a = (int *)malloc(sizeof(int));
	*exam->a = 3;
    printf("exam(%p) a(%p %p %d) b(%p %d) i(%p %d)\n\n", exam, &exam->a, exam->a, *exam->a, &exam->b, exam->b, &i, i);
    //分配了堆区,并把值赋给a,故a的值存在,a指向的堆区的值也存在
    
    free(exam->a);
    printf("exam(%p) a(%p %p %d) b(%p %d) i(%p %d)\n\n", exam, &exam->a, exam->a, *exam->a, &exam->b, exam->b, &i, i);
    //a被free后,a仍指向堆区,只是堆区的内容被清理了
    exam->a = NULL;
    
    printf("exam(%p) a(%p %p) b(%p %d) i(%p %d)\n\n", exam, &exam->a, exam->a, &exam->b, exam->b, &i, i); 
    //指针变量a的地址不变,但其值为NULL;此时再访问*exam->a就会报代码段错误
    
	free(exam);
	printf("exam(%p) a(%p %p) b(%p %d) i(%p %d)\n\n", exam, &exam->a, exam->a, &exam->b, exam->b, &i, i);
	//free:指针变量a的地址不变;b的地址不变,值被清理为随机,i不受影响
	//疑问:a的值为什么又不为NULL了
	
	//exam = NULL;
	printf("exam(%p)\n\n", exam);

	return 0;
}

执行结果:

exam(0x7fff0f2d1d38 (nil)) p(0x7fff0f2d1d48 0x401070)

exam(0x15e8e80) a(0x15e8e80 (nil)) b(0x15e8e88 0)

exam(0x15e8e80) a(0x15e8e80 0x15e8ea0 3) b(0x15e8e88 1) i(0x7fff0f2d1d44 1)

exam(0x15e8e80) a(0x15e8e80 0x15e8ea0 0) b(0x15e8e88 1) i(0x7fff0f2d1d44 1)

exam(0x15e8e80) a(0x15e8e80 (nil)) b(0x15e8e88 1) i(0x7fff0f2d1d44 1)

exam(0x15e8e80) a(0x15e8e80 0x15e8ea0) b(0x15e8e88 22896656) i(0x7fff0f2d1d44 1)

exam(0x15e8e80)

3、指针变量当做数组运用

C语言指针变量可以当做数组运用,在应用之前,应该先让指针指向一个数据块,可以是程序中的某个数组(这个就不说了),也可以指向一段新分配的内存空间;例如:

#include <stdio.h>
#include <stdlib.h>
int main(){
	int i,*p;
	p=(int *)malloc(sizeof(int)*10); //分配10个整数的存储空间,p指针指向该空间
	for(i=0;i<10;i++) 
		p[i]=i; //象平常数组一样访问p指向的存储空间
	for(i=0;i<10;i++)
		printf("%d ",p[i]);
	free(p);  //释放p指向的存储空间。 
}

如果指向新的内存空间时,特别是在子函数中,注意灵活处理要不要释放该存储空间。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值