C语言一些常用内存分配函数

首先看个问题程序(这里用的是TC编译器):
#include "stdlib.h"
#include "stdio.h"
void main()
{
   int *i;
   i=(int
*)malloc(sizeof(int));
   *i=1;
   *(i+1)=2;
   printf("%x|%d\n",i,*i);
  
printf("%x|%d",i+1,*(i+1));
}
输出的结果是:
8fc|1
8fe|2
这个程序编译通过,运行正常,说它有问题,问题出在哪呢?

首先通过malloc,建了一个大小为2的堆,
i指向的地址是8fc,i+1指向的地址是8fc+sizeof(int)=8fe
但是地址8fe是不受保护的,因为它不是机器分配给i+1的,随时会被其他变量占用。

正确的做法是
#include "stdlib.h"
#include "stdio.h"
void main()
{
   int *i;
   i=(int
*)malloc(sizeof(int));
   *i=1;
   i=(int
*)realloc(i,2*sizeof(int));//这里用到了realloc函数,重新分配内存
   *(i+1)=2;
   printf("%x|%d\n",i,*i);
  
printf("%x|%d",i+1,*(i+1));
}
realloc
可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变。

当然,对于缩小,则被缩小的那一部分的内容会丢失。

realloc
并不保证调整后的内存空间和原来的内存空间保持同一内存地址。(几率估计比中六合彩还低)。

相反,realloc 返回的指针很可能指向一个新的地址。
所以,在代码中,我们必须将realloc返回的值,重新赋值给 p :
p = (int *) realloc (p, sizeof(int) *15);

甚至,你可以传一个空指针(0)给 realloc ,则此时realloc 作用完全相当于malloc。
int* p = (int *) realloc (0,sizeof(int) * 10); 
//分配一个全新的内存空间,

这一行,作用完全等同于:
int* p = (int *) malloc(sizeof(int) * 10);

『附注:TC编译器里sizeof(int)=2,VC里面sizeof(int)=4;
char型在两个编译器里是一样的,都是1个字节(8位)』

calloc与malloc相似,参数nelem为申请地址的单位元素长度,elsize为元素个数,如:
char* p;
p=(char*)calloc(sizeof(char),20);
这个例子与上一个效果相同

realloc
可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变(free掉)。

当然,对于缩小,则被缩小的那一部分的内容会丢失。

realloc
并不保证调整后的内存空间和原来的内存空间保持同一内存地址。相反,realloc 返回的指针很可能指向一个新的地址。
所以,在代码中,我们必须将realloc返回的值,重新赋值给 p :
p = (int *) realloc (p, sizeof(int) *15);

时间: 2024-10-11 13:31:01

C语言一些常用内存分配函数的相关文章

C-数组, 字符串的输入输出, 内存分配, 三种内存分配函数

数组初始化 1.数组初始化的时候, 可以这样 1 int len = 3; 2 int arr[len]; 2.但是这样不可以: 1 int len = 3; 2 int arr[len] = {1, 2, 3}; 3.但是可以这样: 1 int arr[3] = {1, 2, 3}; 2不可以的原因: 编译器编译的时候 int arr[3] = {1, 2, 3}这种方式会转换成: 1 int arr[3]; 2 arr[0] = 1; 3 arr[1] = 2; 4 arr[2] = 3;

Linux内核中常见内存分配函数

1.原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分别为: l   页全局目录(Page Global Directory) l   页上级目录(Page Upper Directory) l   页中间目录(Page Middle Directory) l   页表(Page Table) 页全局目录包含若干页上级目录的地址,页上级目录又依次包含若干页中间目录

Linux内核中常见内存分配函数zz

https://blog.csdn.net/wzhwho/article/details/4996510 1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分别为: l         页全局目录(Page Global Directory) l         页上级目录(Page Upper Directory) l         页中间目录(

C语言内存分配函数malloc——————【Badboy】

C语言中经常使用的内存分配函数有malloc.calloc和realloc等三个,当中.最经常使用的肯定是malloc,这里简单说一下这三者的差别和联系. 1.声明 这三个函数都在stdlib.h库文件里,声明例如以下: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(size_t numElements, size_t sizeOfElement); 它们的功能大致类似,

数据结构-c语言内的内存分配

常用到的数据存储区: 在C语言中,根据数据在内存中存在的时间(生存期)不同,将内存空间分为三个区: 1.程序区:用于存储程序的代码,即程序的二进制代码: 2.静态存储区:用于存储全局变量和静态变量,这些变量的空间在程序编译时就已经分配好了: 3.动态存储区:用于在程序执行时分配的内存,又分为:堆区(heap)和堆栈区(stack)两种. 堆区:用于动态内存分配,程序运行时由内存分配函数在堆上分配内存.在C语言中,只要使用指针才能动态的分配内存. 堆栈区:在函数执行时,函数内部的局部变量和函数参数

C语言变量声明内存分配

转载: C语言变量声明内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放. 2.堆区(heap) — 在内存开辟另一块存储区域.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵. 3.全局区(静态区)(static)—编译器编译时即分配内存.全局变量和静态变量

[转载]C语言程序的内存分配方式

"声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要理解错了. ------------------- 1.内存分配方式 内存分配方式有三种: [1]从静态存 储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建. 在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结

数据结构基础(1)--数组C语言实现--动态内存分配

数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数组在删除或者插入元素的时候,要移动元素的坐标不好确定.规律: 1.如果要在数组中第pos个位置插入一个元素(应该从后面开始移动) for( i=cnu;i>=pos;i--) pBase[i]=pBase[i-1]; 2.删除数组第pos位置的元素 for(i=pos+1;i<=cnu;i--)

Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc)

内存分配函数/内存管理API 参考: Windows MSDN http://msdn.microsoft.com/en-us/library/aa908768.aspx 附助资料: http://blog.csdn.net/susubuhui/article/details/7315094 http://wenku.baidu.com/link?url=yxgCWePPV1kFaIUciEspYgm34wNAnMLDoduBlfsEEo-mW0JFRVEOkixomUjPatqw_jOXZcq