c语言数组内存分配动态分配内存的问题,新手,求大神

准备:动态内存分配
一、为什么用动态内存分配
但我们未学习链表的时候,如果要存储数量比较多的同类型或同结构的数据的时候,总是使用一个数组。比如说我们要存储一个班级学生的某科分数,总是定义一个float型(存在0.5分)数组:
float score[30];
但是,在使用数组的时候,总有一个问题困扰着我们:数组应该有多大?
在很多的情况下,你并不能确定要使用多大的数组,比如上例,你可能并不知道该班级的学生的人数,那么你就要把数组定义得足够大。这样,你的程序在运行时就申请了固定大小的你认为足够大的内存空间。即使你知道该班级的学生数,但是如果因为某种特殊原因人数有增加或者减少,你又必须重新去修改程序,扩大数组的存储范围。这种分配固定大小的内存分配方法称之为静态内存分配。但是这种内存分配的方法存在比较严重的缺陷,特别是处理某些问题时:在大多数情况下会浪费大量的内存空间,在少数情况下,当你定义的数组不够大时,可能引起下标越界错误,甚至导致严重后果。
那么有没有其它的方法来解决这样的外呢体呢?有,那就是动态内存分配。
所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。从以上动、静态内存分配比较可以知道动态内存分配相对于景泰内存分配的特点:
1、不需要预先分配存储空间;
2、分配的空间可以根据程序的需要扩大或缩小。
二、如何实现动态内存分配及其管理
要实现根据程序的需要动态分配存储空间,就必须用到以下几个函数
1、malloc函数
malloc函数的原型为:
void *malloc (unsigned int size)
其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。还有一点必须注意的是,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。
下例是一个动态分配的程序:
int count,* /*count是一个计数器,array是一个整型指针,也可以理解为指向一个整型数组的首地址*/
if((array(int *) malloc(10*sizeof(int)))==NULL)
printf(&不能成功分配存储空间。&);
for (count=0;count〈10;count++) /*给数组赋值*/
array[count]=
for(count=0;count〈10;count++) /*打印数组元素*/
printf(&%2d&,array[count]);
上例中动态分配了10个整型存储区域,然后进行赋值并打印。例中if((array(int *) malloc(10*sizeof(int)))==NULL)语句可以分为以下几步:
1)分配10个整型的连续存储空间,并返回一个指向其起始地址的整型指针
2)把此整型指针地址赋给array
3)检测返回值是否为NULL
2、free函数
由于内存区域总是有限的,不能不限制地分配下去,而且一个程序要尽量节省资源,所以当所分配的内存区域不用时,就要释放它,以便其它的变量或者程序使用。这时我们就要用到free函数。
其函数原型是:
void free(void *p)
作用是释放指针p所指向的内存区。
其参数p必须是先前调用malloc函数或calloc函数(另一个动态分配存储区域的函数)时返回的指针。给free函数传递其它的值很可能造成死机或其它灾难性的后果。
注意:这里重要的是指针的值,而不是用来申请动态内存的指针本身。例:
int *p1,*p2;
p1=malloc(10*sizeof(int));
free(p2) /*或者free(p2)*/
malloc返回值赋给p1,又把p1的值赋给p2,所以此时p1,p2都可作为free函数的参数。
malloc函数是对存储区域进行分配的。
free函数是释放已经不用的内存区域的。
所以由这两个函数就可以实现对内存区域进行动态分配并进行简单的管理了。
本文已收录于以下专栏:
相关文章推荐
C语言动态内存分配
       动态数据结构可以在运行时灵活添加、删除或重排数据项。在运行时分配内存空间的过程称为动态内存分配。内存分配函数如下:
malloc   分配所需的字节大小,并返回指...
C语言中手把手教你动态内存分配动态内存分配常见的内存分配的错误先上一个内存分配的思维导图:便于联想想象,理解:
首先我们介绍一下内存分配的方式:1:在静态存储区域中进行分配
内存在程序...
C语言用了蛮久了,最近在写一个dsp的程序,发现动态内存使用这一块还是很欠缺,于是又重新看了看C的书,总结一下。
之前常见的数组或结构体内存分配,其长度必须是固定的常数,如:int a[10]等,当...
// ACM_Easy.cpp : Defines the entry point for the console application.
//C语言动态内存分配
伟大的Bill Gat...
引言:对于指针,正确的分配动态内存是十分重要的,本文将着重阐述动态内存分配函数malloc,calloc,realloc以及memset的用法。
  一、对于malloc,在终端输入 #:man  ...
一. 传统数组的缺点:  
1. 数组的长度事先指定,且只能是常整数,不能是变量。例如:
int a[5]; //这行代码正确
int len =5; int a[len]; /...
他的最新文章
讲师:姜飞俊
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)c语言指针、动态分配内存例题
void getMemeory1(char *p)
&& p = (char
*)malloc(100*sizeof(char));
char * getMemeory2()
&& char p[100] = "Hello
int main()
&&& char *str1 =
getMemeory1(str1);
&& &strcpy(str1,
"Hello world");
&&&&printf("str1
= %s\n", str1);
&&& char *str2 =
&& &str2 =
getMemeory2();
&&& printf("str2
= %s\n", str2);
执行结果:test1程序报错,test2打印乱码或者“Hello world”(一般乱码)
结果分析:
在函数中给指针分配空间,实际上是给指针的临时变量分配空间,函数结束后,这个临时变量也消亡,而str仍然为NULL,没有为其分配空间,此时strcpy()是肯定会出错的。
1、可能是乱码,也有可能是正常输出,因为GetMemory返回的是指向“栈内存”的指针,该指针的地址
不是NULL,但其原来的内容已经被清除,新内容不可知,程序员面试宝典里有专门讲该部分知识的。
2、因为p的生命周期在GetMemory函数执行完了就被销毁了,str
指向的是个野指针。&&&&&&&
//相关分析资料摘录
1、指针参数是如何传递内存的?
  如果函数的参数是一个指针,不要指望用该指针去申请动态内存。以下Test函数的语句GetMemory(str, 200)并没有使str获得期望的内存,str依旧是NULL,为什么?
void GetMemory(char *p, int num)
 p = (char
*)malloc(sizeof(char) * num);
void Test(void)
 char *str =
 GetMemory(str, 100); //
str 仍然为 NULL
 strcpy(str, "hello");
// 运行错误
试图用指针参数申请动态内存
  毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p =
p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。  如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例1.2。
void GetMemory2(char **p, int num)
 *p = (char
*)malloc(sizeof(char) * num);
void Test2(void)
 char *str =
 GetMemory2(&str, 100); // 注意参数是
&str,而不是str
 strcpy(str,
 cout&& str
 free(str);
示例1.2用指向指针的指针申请动态内存
  由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。这种方法更加简单,见示例1.3。
char *GetMemory3(int num)
 char *p = (char
*)malloc(sizeof(char) * num);
void Test3(void)
 char *str =
GetMemory3(100);
 strcpy(str,
 cout&& str
 free(str);
用函数返回值来传递动态内存
  用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡,见示例1.4。
char *GetString(void)
 char p[] = "hello
编译器将提出警告
void Test4(void)
 char *str =
 str = GetString(); //
str 的内容是垃圾
 cout&& str
return语句返回指向“栈内存”的指针
  用调试器逐步跟踪Test4,发现执行str = GetString语句后str不再是NULL指针,但是str的内容不是“hello world”而是垃圾。如果把示例1.4改写成示例1.5,会怎么样?
char *GetString2(void)
 char *p = "hello
void Test5(void)
 char *str =
GetString2();
 cout&& str
return语句返回常量字符串
  函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为GetString2内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。
  2、杜绝“野指针”
  “野指针”不是NULL指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if语句对它不起作用。 “野指针”的成因主要有两种:
  (1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
char *p = NULL;
char *str = (char *) malloc(100);
(2)指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。
  (3)指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:
  void Func(void){ cout
&& “Func of class A” &&
void Test(void)
  p = &a;
 p-&Func(); //
p是“野指针”
函数Test在执行语句p-&Func()时,对象a已经消失,而p是指向a的,所以p就成了“野指针”。但奇怪的是我运行这个程序时居然没有出错,这可能与编译器有关。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。C语言中的动态内存分配的用法举例-C语言中的动态内存分配-malloc的用法 _新知资讯资讯
C语言中的动态内存分配的用法举例
C语言中的动态内存分配的用法举例
count++) /
array[count]= for(count=0。
注意:这里重要的是指针的值,* /*count是一个计数器:
1)分配10个整型的连续存储空间,并返回一个指向其起始地址的整型指针
2)把此整型指针地址赋给array
3)检测返回值是否为NULL
2、free函数
由于内存区域总是有限的,不能不限制地分配下去,而且一个程序要尽量节省资源;不能成功分配存储空间。&);
exit(1); } for (count=0;count〈10:void *malloc (u igned int size)
其作用是在内存的动态存储区中分配一个长度为size的连续空间://www:#include #include main(){ int count。
free函数是释放已经不用的内存区域的,而不是用来申请动态内存的指针本身。例:int *p1,*p2;p1=malloc(10*sizeof(int));p2=p1;……free(p2) /*或者free(p2)*&#47,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。
下例是一个动态分配的程序://www。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。还有一点必须注意的是,p2都可作为free函数的参数。例中if((array(int *) malloc(10*sizeof(int)))==NULL)语句可以分为以下几步,所以当所分配的内存区域不用时,就要释放它,以便其它的变量或者程序使用。这时我们就要用到free函数;
malloc返回值赋给p1;,array[count]);}
上例中动态分配了10个整型存储区域./article//ps_5531.html" target="_blank">http,array是一个整型指针,也可以理解为指向一个整型数组的首地址*/ if((array(int *) malloc(10*sizeof(int)))==NULL) {
printf(&%2d&*给数组赋值*&#47。参考资料。
其函数原型是:void free(void *p)
作用是释放指针p所指向的内存区。
其参数p必须是先前调用malloc函数或calloc函数(另一个动态分配存储区域的函数)时返回的指针:
clear screen
p=(char *)malloc(100);
printf(&Memory Allocated at: %x&quot。
当内存不再使用时,应使用free()函数将内存块释放。
/&#47:#include &alloc.h&
printf(&Not Enough Memory!&#92:如果分配成功则返回指向被分配内存的指针;
功能:分配长度为num_bytes字节的内存块
clrscr(),否则返回空指针NULL;
#include &alloc.h&,p);
// malloc.c
#include &syslib.h&n&);
getchar();
return 0例如malloc,zizeof,free等原型:extern void *malloc(unsigned int num_bytes);
#include &stdio.h&#include &stdlib.h&#define STR_LEN 4096int main () {char * str = malloc(STR_LEN);scanf(&%s&, str);printf(&%s\n&, str);free(str);return 0;}
你可能感兴趣的相关内容C语言内存动态分配问题 - ITeye问答
下面是一个有关C的内存动态分配问题,在程序中有个问题有点疑惑,请大家指点。
代码如下:
#include &stdio.h&
#include &stdlib.h&
#include &stdarg.h&
#include &math.h&
#define space printf("\n")
#define null 0
void main()
{
&& int *p,i;
&& p=malloc(10*sizeof(int)); //获得存储10个整型元素的空间
&& printf("p=%x\n",p);&&&&&& //打印出p在指向空间的起始地址
&& if(p!=null){
&&&& for(i=0;i&10;i++,p++) {
&&&&&& *p=2*i;
&&&& }
&& }else{
&&&&& printf("Memory is Out!\n");
&& }
for(i=0;i&10;i++,p--){
& printf("第%d个数地址=%x,值为=%d \n",(10-i),p,*p);
}
printf("p=%x\n",p);
free(p); //释放内存
system("pause");
}
在这个程序中明明是向内存请求10个int类型的整数,p=malloc(10*sizeof(int));
p的起始地址为Start_Address=Ox383190 ,结束地址End_Address=Ox3831b8
该程序的输出结果如下:
第10个数的地址为:Ox3831b8,值为: -
第9个数的地址为:Ox3831b4,值为: 18
第8个数的地址为:Ox3831b0,值为: 16
第7个数的地址为:Ox3831ac,值为: 14
第6个数的地址为:Ox3831a8,值为: 12
第5个数的地址为:Ox3831a4,值为: 10
第4个数的地址为:Ox3831a0,值为: 8
第3个数的地址为:Ox38319c,值为: 6
第2个数的地址为:Ox383198,值为: 4
第1个数的地址为:Ox383194,值为: 2
(1) 该程序中在起始位置(Ox383190)的0怎么没有输出,第一个值应该是0呀,疑惑 ?
目前还没有答案
已解决问题
未解决问题

我要回帖

更多关于 c语言分配内存函数 的文章

 

随机推荐