您的位置:首页 > 房产 > 家装 > python基础教程for循环_怎么找公众号帮推广_建网站公司哪里好_关键词名词解释

python基础教程for循环_怎么找公众号帮推广_建网站公司哪里好_关键词名词解释

2025/3/10 22:38:58 来源:https://blog.csdn.net/chenyuhao2024/article/details/146077784  浏览:    关键词:python基础教程for循环_怎么找公众号帮推广_建网站公司哪里好_关键词名词解释
python基础教程for循环_怎么找公众号帮推广_建网站公司哪里好_关键词名词解释

hello,everyone!

承接上次的动态内存的分享,我想想还是把具体的易错点分享一下,再跟大家分享四道非常经典的笔试题,以后找工作会发现,很多题就是这四道题的原型。

话不多说开始

1. 内存泄漏 

程序分配了内存但没有释放,导致内存被持续占用,最终可能导致系统内存耗尽。

原因: 忘记调用 free或 delete释放内存。

忘记释放不再使用的动态开辟的空间会造成内存泄漏。 切记: 动态开辟的空间一定要释放,并且正确释放 。

void memoryLeak() {int *ptr = (int*)malloc(sizeof(int));// 忘记释放内存
}

2. 野指针

描指针指向的内存已经被释放,但指针仍然被使用。

原因: 在释放内存后继续使用指针,或返回局部变量的指针。

int* danglingPointer() {int *ptr = (int*)malloc(sizeof(int));free(ptr);return ptr; // ptr 现在是野指针
}

3. 双重释放

对同一块内存多次调用 free 或 delete。

原因: 释放已经释放过的内存。

void doubleFree() {int *ptr = (int*)malloc(sizeof(int));free(ptr);free(ptr); // 双重释放
}

4. 内存越界

访问了分配内存之外的区域,可能导致数据损坏或程序崩溃。

原因: 数组越界、指针操作超出分配的内存范围。

void bufferOverflow() {int *ptr = (int*)malloc(5 * sizeof(int));ptr[5] = 10; // 越界访问
}

5. 无效指针解引用

解引用无效的指针(如空指针或未分配内存的指针)。

原因: 指针未正确初始化或已被释放。

void invalidDereference() {int *ptr = NULL;*ptr = 10; // 解引用空指针
}

6.忘记检查分配是否成功

未检查内存分配是否成功,可能导致后续操作出错。

原因: 假设 malloc 或 new 总是成功。

void noCheckAllocation() {int *ptr = (int*)malloc(1000000000 * sizeof(int));*ptr = 10; // 如果分配失败,ptr 为 NULL
}

好了,我们接下来就来看一下这四道题。看一下这些代码错误在哪里,运行能得到什么结果

test1

void GetMemory(char *p)
{p = (char *)malloc(100);
}
void Test(void)
{char *str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);
}

这个代码严谨一点的话有三个问题:

1.函数参数传递2.内存泄漏3.未检查内存分配是否成功。

先来看第一个GetMemory 函数的参数 p 是一个指针,但它是按值传递的。即使 p 在函数内部被修改为指向新分配的内存,调用方的 str 并不会被更新,仍然为 NULL。
因此,Test 函数中的 str 仍然是 NULL,导致 strcpy 和 printf 操作是未定义行为。GetMemory 函数中分配的内存没有被释放,导致内存泄漏。另外malloc 可能会失败并返回 NULL,但代码没有检查分配是否成功。

那怎么改呢?

利用二级指针就可以。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void GetMemory(char **p) {*p = (char *)malloc(100);if (*p == NULL) {fprintf(stderr, "Memory allocation failed\n");exit(1);}
}void Test(void) {char *str = NULL;GetMemory(&str); // 传递 str 的地址strcpy(str, "hello world");printf("%s\n", str);free(str); // 释放内存
}int main() {Test();return 0;
}

test2

char *GetMemory(void) 
{ 
char p[] = "hello world"; 
return p; 
} 
void Test(void) 
{ 
char *str = NULL; 
str = GetMemory(); 
printf(str); 
} 

这段代码的问题是返回局部变量的指针和未初始化指针。

在 GetMemory 函数中,p 是一个局部数组,它的内存位于栈上。当函数返回时,栈帧会被销毁,p 的内存不再有效。
因此,GetMemory 返回的指针指向一个无效的内存区域,导致 Test 函数中的 printf 操作会引发未定义行为(表现通常是打印乱码或程序崩溃)。

在 Test 函数中,str 被初始化为 NULL,但通过 GetMemory 赋值后,它指向了一个无效的内存地址。

这里的改变我们可以将局部变量声明为 static,使其生命周期延长到程序结束。这个后面两篇文章会讲。为什么static能延长生命周期。

这里粘贴一下,满足一下大家的好奇心。

#include <stdio.h>char* GetMemory(void) {static char p[] = "hello world"; return p;
}void Test(void) {char *str = NULL;str = GetMemory(); printf("%s\n", str);
}int main() {Test();return 0;
}

好了,感谢阅读,剩下的我们下一篇文章讲,希望大家好好理解这两道题。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com