为何此场景无需调用free()?malloc/free无效指针错误原因咨询
问题原因分析
你猜的没错!问题**确实出在把循环变量i的地址赋值给ptr**上,咱们一步步拆解清楚:
- 初始状态:
int *ptr = malloc(sizeof(int) * num);这里ptr指向的是堆内存(由malloc分配的动态内存),这部分内存是需要用free释放的合法对象。 - 循环里的致命操作:
ptr = &i;这行代码直接把ptr的指向彻底改了——现在ptr指向的是循环变量i的地址,而i是定义在栈上的局部变量,属于栈内存范畴,根本不是malloc分配的堆内存。 - 最后的非法
free:此时调用free(ptr);,相当于让free去释放一块栈内存,但free的规则是只能释放由malloc/calloc/realloc分配的堆内存,尝试释放栈内存属于越界操作,必然触发你看到的「invalid pointer」错误。
另外还有个隐藏坑:你一开始用malloc分配的堆内存,在ptr被重新赋值后,就彻底丢失了它的地址——这会导致内存泄漏,那块堆内存会一直占用直到程序退出。
修复建议
如果你的目的是用ptr存储循环里的i值,别修改ptr的指向,而是给ptr指向的内存空间赋值:
#include <stdio.h> #include <stdlib.h> int main() { int num; printf("Give me a number:\n"); scanf("%d", &num); int *ptr = malloc(sizeof(int) * num); // 先检查malloc是否成功,避免空指针问题 if (ptr == NULL) { printf("Memory allocation failed!\n"); return 1; } for (int i = 0; i < num; ++i) { // 给ptr指向的第i个元素赋值,而非修改ptr本身的指向 ptr[i] = i; printf("%d\n", ptr[i]); } free(ptr); // 此时ptr仍指向malloc分配的堆内存,释放操作合法 return 0; }
这样修改后,ptr全程指向堆内存,free操作就合法了,也解决了内存泄漏的问题。
内容的提问来源于stack exchange,提问作者akrilmokus
相关产品推荐
相关产品推荐

