关于C语言内存分配的两个疑问:越界访问与内存泄漏
问题1:内存越界写入的危害
你这段代码里,malloc(1*sizeof(char))只分配了1字节的堆内存,但后续通过c[1]到c[4]进行了越界写入,当前能正常输出只是未定义行为的一种巧合——这块内存后面的区域刚好暂时未被其他数据占用,也没破坏堆的管理结构。但这种写法的危害非常严重:
- 破坏堆结构,导致程序崩溃:堆内存有自身的管理元数据(比如内存块的大小、前后块指针),越界写入可能覆盖这些元数据,后续调用
free或其他malloc时会触发错误,直接导致程序崩溃。 - 覆盖其他变量数据,引发逻辑错误:如果越界区域刚好是其他堆变量的内存,会篡改这些变量的值,导致程序出现莫名其妙的逻辑错误,排查难度极大。
- 触发内存保护机制:现代操作系统的内存保护(比如ASLR、堆保护)可能直接检测到越界访问,强制终止程序。
- 安全漏洞:这种堆缓冲区溢出可能被攻击者利用,篡改程序执行流程,执行恶意代码,属于高危安全隐患。
你的代码示例:
int main() { char *c = (char*)malloc(1*sizeof(char)); c[0]='1'; c[1] ='2'; c[2]='4'; c[3]='3'; c[4]='6'; c[5]='\0'; printf("%s",c); free(c); return 0; }
问题2:被覆盖的内存会发生内存泄漏
你这段代码中,最初char *d = (char*) malloc(1*sizeof(char));分配的1字节堆内存,会因为后续d= mallocbyme();的赋值操作导致内存泄漏:
- 指针
d原本指向那块1字节内存的地址,但赋值后d指向了mallocbyme函数返回的新内存地址,原来的地址没有被保存,也没有调用free释放。 - 这块被遗忘的内存,在程序运行期间无法被回收复用,直到进程结束后才会被操作系统回收。如果这类操作频繁发生,会持续消耗系统内存,最终导致内存耗尽。
你的代码示例:
char * mallocbyme() { char *f = (char*) malloc(4*sizeof(char)); return f; } char *d = (char*) malloc(1*sizeof(char)); d= mallocbyme();
内容的提问来源于stack exchange,提问作者tonyjk
相关产品推荐
相关产品推荐

