内存分配方式有三种:
1.从静态存储区域分配。在程序编译的时候就分配好了内存,这个内存在程序的整个运行期间都存在。
例如 全局变量,static变量。
2.在栈上创建。在执行函数时,函数内局部变量的存储单元在栈上创建,函数执行结束时这些存储单元自动被释放。
效率比较高,但是分配的内存容量有限。
3.从堆上分配,即动态内存分配。用malloc或new申请任意多少的内存。用free或delete释放内存。
常见的内存错误:
1.内存分配未成功,却使用了它。
如果指针P是函数的参数 那么在函数的入口处用assert(p!=null)进行检查。
如果用malloc或者new来申请内存,用if(p==null) 或 if(p!=null)来进行防错处理。
2.内存分配成功,但是尚未初始化就引用它。
无论以何种方式创建数组,被忘了赋初值。
char *p = malloc(10);
memset(p,'\0',10);
3.内存分配成功并且已经初始化,但是内存越界了。
char *ptr = (char *) malloc(10)
char name[20]
memcpy(name,ptr,20)
4.忘记了释放内存,造成内存泄露。
5.释放了内存,却还在使用它。
a).返回的是“栈内存”的指针,因为该内存在函数体结束时被自动销毁。
b).使用free或者delete释放内存后,没有将指针设置为NULL,导致“野指针”。
错误范例:
1.void GetMemmory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL; //申请一个char类型的指针str,并把str指向NULL(即str里存的是NULL的地址,*str为NULL中的值为0),
GetMemmory(str);
strcpy(str,"hello world");
printf(str);
}
2.char *GetMemory(void)
{
char p[] = "hello world" ; //此行将p[]改成*p就对了,此时p[]存在于栈里边,*p的话字符串存于常量区
return p; //return数组名后,会释放掉它里面所有的变量所占用的空间,所以数组空间被释放掉了.
}
void Test(void)
{
char *str =NULL;
str = GetMemory();
printf(str);
}
3.void GetMemory2(char **p, int num)
{ *p = (char *)malloc(num); } void Test(void) { char *str = NULL; GetMemory(&str,100); strcpy(str,hello); printf(str); } 4.void Test(void)
{ char *str = (char *)malloc(100); strcpy(str,hello); free(str); if(str != NULL) //一个指针被释放之后其内容并不是NULL,而是一个不确定的值 { strcpy(str,world); printf(str); } } |
|
来自: audrey_guowei > 《C语言面试》