C语言:动态内存错误
Posted 往明
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言:动态内存错误相关的知识,希望对你有一定的参考价值。
导航
⭐️前言⭐️
经过前面动态内存相关知识的学习,我们本文就要来分析动态内存相关的问题。
🍃常见内存错误
🍂对NULL指针的解引用操作
void test(){
int* p = (int*)malloc(INT_MAX*sizeof(int));
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
🍂越界访问
void test(){
int i = 0;
int* p = (int*)malloc(10 * sizeof(int));
if (NULL == p){
exit(EXIT_FAILURE);
}
for (i = 0; i <= 10; i++){
*(p + i) = i;//当i是10的时候越界访问
}
free(p);
}
🍂对非动态开辟内存使用free释放
void test(){
int a = 10;
int* p = &a;
free(p);//ok?
}
🍂使用free释放一块动态开辟内存的一部分
void test() {
int* p = (int*)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
🍂对同一块动态内存多次释放
void test(){
int* p = (int*)malloc(100);
free(p);
free(p);//重复释放
}
🍂内存泄漏
void test(){
int* p = (int*)malloc(100);
if (NULL != p){
*p = 20;
}
}
int main(){
test();
while (1);
}
🍃动态内存错误笔试题分析
🍂笔试题1
以下代码执行效果
void GetMemory(char* p){
p = (char*)malloc(100);
}
void Test(){
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf("%s",str);
}
int main() {
Test();
return 0;
}
执行后:程序会崩溃
分析如下:
我们经过调试发现再执行GetMemory(str);
后str的地址还是等于NULL,那这是为什么呢?
那肯定是这个函数处理不当?
突然想起函数传递参数–传值调用,如下
void change(int a) {
a = a + 1;
}
int main() {
int a = 0;
change(a);
return 0;
}
在执行完后看似a的值加一,但是我们发现它还是0
对于这种情况也是一样,传值调用并不能改变值,要想达到目的需要进行传址调用。
void GetMemory(char** p){
*p = (char*)malloc(100);
}
void Test(){
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
}
int main() {
Test();
return 0;
}
🍂笔试题2
char* GetMemory(void){
char p[] = "hello world";
return p;
}
void Test(void){
char* str = NULL;
str = GetMemory();
printf(str);
}
int main() {
Test();
return 0;
}
输出随机值
str接受了p的地址,但是在GetMemory函数结束后销毁,p函数中内存内容也被随机化,虽然拿到了地址,但是内容不再是hello world
这种情况对应野指针,指针指向的内容已被释放,对其解引用就会出错
int* change() {
int n = 10;
return &n;
}
int main() {
int* p = change();
printf(" \\n");
printf("%d", *p);
return 0;
}
输出的不是我们想要的10
🍂笔试题3
void GetMemory(char** p, int num){
*p = (char*)malloc(num);
}
void Test(void){
char* str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
int main() {
Test();
return 0;
}
这道题就是笔试题1的正确写法,输出
hello
🍂笔试题4
void Test(void){
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL){
strcpy(str, "world");
printf(str);
}
}
int main() {
Test();
return 0;
}
输出hello,word
分析:
对于第一个输出hello很容易判断,在释放后str的内容虽然丢失了,但是str的地址还在,不为空,所以world被拷贝进去。
这也是前文介绍在释放后需要把指针指向NULL
⭐️结尾语⭐️
相关链接
⭐️上一篇:动态内存管理知识⭐️
⭐️下一篇:暂未更新⭐️
⭐️传值调用以及传值调用:函数⭐️
以上是关于C语言:动态内存错误的主要内容,如果未能解决你的问题,请参考以下文章