c语言malloc头文件_c语言指针的有关总结

指针

  • 指针的概念

    • 1:对内存的理解

    • 2:地址

    • (重点)指针定义

  • 与指针有关的运用

    • 1:c语言动态内存管理

    • 2:内存泄漏?

指针的概念

1:对内存的理解

这是我们计算机的内存条。这当然是我们的物理内存594a0b24527f6dc9c1b3407d9ea0f2f7.png
这是我们的虚拟内存0640bca60e79fbd65fc0f0d1f428d94a.png
像我们可以写程序来操纵计算机内存这样子。
或者我们可以这样认为,物理内存是可以看得见,摸得着的,而虚拟内存反之。

计算机所有的程序都需要内存来执行。

2:地址

在计算机中,内存是以字节为单位的存储空间,每个字节都有他自己的一个编号,这个编号就被称为内存地址。内存地址是存储数据的标志,可以理解为我们家的门牌号,通过门牌号可以找到里面的成员。内存数据所在内存中存储的位置就用内存地址来标识。

我们在c语言中在定义一个变量时,系统就会为该变量分配内存空间,当我们赋值时,那么就相当于往杯子里装了水一样。

我们来看一个程序0a57d10f89358003da6ecf5ae31dbff4.png
我们来看一个运行结果f4742181c79e99e0f7e3bb92603cfabd.png
我们在定义num的时候,系统为它分配了空间,我们初始化,那么就是给杯子里装上了水。当然我们可以用键盘的输入----scanf()函数,
如下:362b0fb61e601c724c06d07fe49fa9b0.png
我们可以看到这个&号,叫做取地址符,我们要键盘输入赋值,首先要找到他的内存地址才可以,就好像送货上门,你得根据门牌号来送货。
如果我们在定义变量时未赋值,在控制台输出这个变量的值出现什么结果?6c69a18c6e45c52ee750685ec37a3cfa.png402fc31d731ba137d1088eae038408ff.png
程序给了他一个33。当然在不同编辑器下的情况可能不同。像vc++会赋初值为0。
我们来看一个char类型的变量,遇到同样的情况,会是什么值?fc53f665e400d1339e67a13495dbaaeb.png7d4417d948e4e2144644a4bf4547baa6.png
codeBlocks给了一个空。
现在我们写一个程序,来访闻下相关变量的地址
我们这样写,并可能会发现一些有趣的d2ec00e04686d022f0ffdd762490a29c.png
我们来看运行结果01231ab42fb1281c2faeee3df9e8abea.png
我们可以看到他们的地,然后也会发现,在数组中取地址 ch 和&ch是等价的,我们还可以看到连续的数组里的地址,&char[0],&char[1]。非常有趣,更多的大家可以自己尝试。

(重点)指针定义

e0f6296ec5c33fea2863a8638fc777df.png指针:指针我们可以理解为变量的地址,也就但同于变量的地址。看一些资料容易混淆指针变量和和指针的区别,指针变量时存放地址的变量,而指针则等用于地址。有时候会把指针变量简称为指针,所以时常在碰上真正的概念区别时,反而晕了。

ok,我们用代码来证明e8161471bbec912078700c4e39000149.png
我们来看运行结果6e18d8ef01e9766af72af3ea7b0fe833.png

我们可以看到,两者是等价的,撸一串代码对于概念的理解也很有帮助。

与指针有关的运用

1:c语言动态内存管理

指针的一个意义在于更方便的管理我们的内存空间。
我们来介绍几种函数。
1:void* malloc(size_t size)void*(无值型)所以这个是可以强制转换的,可以转换成需要的指针。
malloc函数用来开辟一段连续的内存空间,开辟成功返回值为这块内存空间的地址,开辟失败返回值为NULL,size为空间的大小,单位为字节。在用malloc开辟空间后要检查是否开辟内存成功,使用完这段内存后要用free(void* ptr)释放内存,否则会造成内存泄漏。
例如:

int *p1;
double *p2;
p1 = (int)*malloc(4);
p2 =(double*)malloc(8);
  • 1

  • 2

  • 3

  • 4

我们来看一个例子591ec0b24c153a9349ee3081e72c9236.png
如果没有看清图片,我们来看代码片

#include
int main()
{
int *ptr;
ptr =(int*)malloc(sizeof(int));
if(ptr==NULL)
{
printf("分配内存空间失败");
exit(1);//退出
}
printf("请输入一个整数 ");
scanf("%d",ptr);
printf("你输入的整数是: %d\n",*ptr);
free(ptr);//释放掉指针
return 0;
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

我们来看运行结果cf463c7a89045d56d61b27bea0b300d6.png这里我们注意一点,由于并不是所有的操作系统都是四个字节,所以我们要用到sizeof。

我们再来看一个程序,功能是根据用户输入整数的个数来申请空间。

652ce74677453f179edef292860bf879.png
我们来看代码片

include
#include
int main()
{
int *ptr=NULL;
int num,i;
printf("请输入整数的个数:");
scanf("%d",&num);
ptr =(int*)malloc(num*sizeof(int));
for(i=0;i
printf("请录入第%d个整数:",i+1);
scanf("%d",&ptr[i]);
}
printf("您录入的整数是:");
for(i=0;i printf("%d",ptr[i]);
}
free(ptr);
return 0;
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

ok,我们来看运行效果bbc2365de6898dcbe5a4c8bc78e757fa.png
2:void *memset(void *str, int c, size_t n)
memset 函数是内存赋值函数,用来给某一块内存空间进行赋值的;

包含在头文件中,可以用它对一片内存空间逐字节进行初始化;
我们来看具体代码运用97961d4bffdb2d50419a755ca9780b45.png
我们来看代码片
下面展示一些 内联代码片

#include
#include
#include
#define N 10
int main(){
int *ptr =NULL;
int i;
ptr=(int *)malloc(N * sizeof(int));
if(ptr ==NULL){
printf("空间申请失败");
exit(1);
}
memset(ptr,0,N*sizeof(int));
for(i=0;i printf("%d",ptr[i]);
}
putchar('\n');
free(ptr);
return 0;
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

我们来看运行结果
我们给了十个空间,都被程序给了0,因为我们没有赋值。7447d919101dc15e8e24d23b4da4d7a4.png
3:void *memcpy(void *dest, const void *src, size_t n)
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
就像这样,我们来简单看个代码片
下面展示一些 内联代码片

#include
#include
#include
int main(void){
int *ptr1 =NULL;
int *ptr2 =NULL;
ptr1 = (int*)malloc(10*sizeof(int));
ptr2 =(int *)malloc(20*sizeof(int));
//将ptr1的数据拷贝到ptr2中
memcpy(ptr2,ptr1,10);
free(ptr1);//我们将ptr1释放掉。
return 0;
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

4:void* realloc(void* ptr,size_t size)
malloc或calloc开辟的空间进行扩容,ptr为malloc或calloc的起始地址,size为新开辟的空间的大小。
我们来看代码片
下面展示一些 内联代码片

#include
#include
int main(){
int i,num;
int countq =0;
int *ptr = NULL;//初始化NULL
while(num!=-1){
printf("请输入一个整数,输入-1表示结束:");
scanf("%d",&num);
countq++;
ptr = (int*)realloc(ptr,countq*sizeof(int));
if(ptr==NULL){
printf("空间申请失败");
exit(1);
}
ptr[countq-1] =num;
}
printf("输入的整数分别是:");
for(i=0;i printf("%d",ptr[i]);
}
putchar('\n');
free(ptr);
return 0;
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

  • 16

  • 17

  • 18

  • 19

  • 20

  • 21

  • 22

  • 23

  • 24

  • 25

  • 26

我们来看运行结果6b297c8b5b1d49d503487acabea7599d.png
ok。
5:void* calloc(size_t num,size_t size)
calloc函数用来开辟num个size大小连续的内存空间,开辟成功返回值为这块内存空间的地址,开辟失败返回值为NULL。在用calloc开辟空间后要检查是否开辟内存成功,使用完这段内存后要用free(void* ptr)释放内存,否则会造成内存泄漏。
相关的操作大同小异,就不再赘述。

2:内存泄漏?

内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

这这这。。。就关系到我们在空间管理上的合理运用。
好啦,我们极端的举个例子
下面展示一些 内联代码片

#include
#include
int main(void)
{
while(1){
malloc(1024);
}
getchar();
return 0;
}
  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

代码短小精干,但原理涉及到计算机的内部。代码的长短决定不了代码的1功能和效果。

如果,没有管家的朋友们,可以试试运行这段代码。我的电脑管家会直接判断这是纳尼木马,连可执行文件都不让生成。
如果有兴趣的朋友,可以关掉杀毒,运行一下,你的电脑会假死后回来。cfdb3c52d09e64329ad24d55643ca71f.png

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值