文章目录
- 前言
- 一、常见的动态内存错误
- 1. 对NULL指针的解引用操作
- 2. 对动态开辟空间的越界访问
- 3. 对非动态开辟内存使用free()
- 4. 使用free释放一块动态开辟内存的一部分
- 5. 对同一块动态内存多次释放
- 6. 动态开辟内存忘记释放(内存泄漏)
- 二、几个经典笔试题
- 1.
- 2.
- 3.
- 4.
- 三、 c/c++内存开辟空间图
- 总结
前言
C语言常见的动态内存错误及几个经典笔试题以及c/c++内存开辟空间等的介绍
一、常见的动态内存错误
1. 对NULL指针的解引用操作
#include <stdio.h>
#include <stdlib.h>
int main()
{int* p = (int*)malloc(40);// 没有对malloc开辟失败的拦截,所以p有可能为空指针// 程序可能崩溃*p = 20;return 0;
}
2. 对动态开辟空间的越界访问
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{int* p = (int*)malloc(40);if (NULL == p){printf("%s\n", strerror(errno));}int i = 0;for (i = 0; i <= 10; i++) // 动态内存越界访问,程序报错{*(p + i) = i;}free(p);p = NULL;return 0;
}
3. 对非动态开辟内存使用free()
#include <stdio.h>
#include <stdlib.h>
int main()
{int a = 0;int* p = &a;free(p);p = NULL;return 0;
}
4. 使用free释放一块动态开辟内存的一部分
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{int* p =(int*)malloc(40);if (NULL == p){printf("%s\n", strerror(errno));}int i = 0;for (i = 0; i < 5; i++){*p = i;p++; // p 的地址一直在改变,free(p)没有指向动态内存的起始地址// 程序崩溃}free(p);p = NULL;return 0;
}
5. 对同一块动态内存多次释放
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{int* p = (int*)malloc(40);// ....free(p); // 释放了一次,但是p没有置为空指针// 此时p为野指针// p = NULL;// .....free(p); // 此时程序报错,p是野指针return 0;
}
6. 动态开辟内存忘记释放(内存泄漏)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void test()
{int* p = (int*)malloc(40);if (NULL == p){printf("%s\n", strerror(errno));return;}int flag = 0;scanf("%d", &flag);if (flag == 5){return;}free(p);p = NULL;
}int main()
{test();return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int* test()
{int* p = (int*)malloc(40);if (NULL == p){return p;}return p;}int main()
{// test 函数开辟空间int* ret = test();// 忘记释放return 0;
}
所以,动态开辟的空间一定要释放,并且要正确释放。
二、几个经典笔试题
1.
char* str = "hello world";
printf(“%s\n”, str); // hello world
printf(“hello world”\n); // hello world
printf(str) // hello world
str 存放 h 的地址, 所以 printf(""hello world); 和 printf(str);是一样的效果
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char* p)
{p = (char*)malloc(100);// 出了GetMemory函数 p会被销毁// 无法再找到 动态内存,所以内存泄漏
}void Test(void)
{char* str = NULL;GetMemory(str);// str 是空指针,解引用时,程序崩溃strcpy(str, "hello world");printf(str);
}int main()
{Test();return 0;
}
- 修改1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char** p)
{*p = (char*)malloc(100);// *p 指向str,str被赋值为动态内存的地址
}void Test(void)
{char* str = NULL;GetMemory(&str);strcpy(str, "hello world"); // hello worldprintf(str);free(str);str = NULL;
}int main()
{Test();return 0;
}
- 修改2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* GetMemory()
{char* p = (char*)malloc(100);// *p 指向str,str被赋值为动态内存的地址return p;
}void Test(void)
{char* str = NULL;str = GetMemory();strcpy(str, "hello world"); // hello worldprintf(str);free(str);str = NULL;
}int main()
{Test();return 0;
}
2.
#include <stdio.h>
#include <string.h>
char* GetMemory(void)
{char p[] = "hello world";return p; // 出了 函数 ,p[] 就会被销毁// 所以str 接收到了地址,但是p[]的内容被销毁, 无法被找到
}
void Test(void)
{char* str = NULL;str = GetMemory(); // str 是一个野指针printf(str); // 烫烫烫烫烫烫烫烫x魪?
}int main()
{Test();return 0;
}
3.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* GetMemory(char** p, int num)
{*p = (char*)malloc(num);
}
void Test(void)
{char* str = NULL;GetMemory(&str, 100); strcpy(str, "hello");printf(str); // hello// 但是没有释放内存空间// 可以如下释放/*free(str);str = NULL;*/
}int main()
{Test();return 0;
}
4.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>void Test(void)
{char* str = (char*)malloc(100);strcpy(str, "hello");free(str); // 释放空间,str变成野指针if (str != NULL){strcpy(str, "world");printf(str);}
}int main()
{Test();return 0;
}
三、 c/c++内存开辟空间图
总结
C语言常见的动态内存错误及几个经典笔试题以及c/c++内存开辟空间等的介绍