【发布时间】:2020-07-22 13:26:13
【问题描述】:
在熟悉指针之后,我遇到了使用 malloc() 和 free() 进行动态内存分配的部分。我想确认或更正我对这个话题的理解。
直到现在,我才明白指针的巨大好处有两个:
- 通过引用调用(即可以使用指针访问和更改函数外部的变量,而无需全局变量)。
- 使用指针算法,它是一种非常方便且代码高效的方式来遍历数组(例如,作为字符串的 char 数组),访问和操作数据。
谈到 malloc(),我觉得如果指针地址没有被重置,指针算术会变得非常危险。给定下面的示例,我使用 malloc() 创建了两个指针 ptr 和 ptr1。 我理解这两个 malloc() 函数分配了两个内存块,每个都和 size*sizeof(int) 一样大,所以这是保留内存,这两个块的第一个元素的地址给 ptr 和 ptr1。
使用第一个 for 循环,我使用指针将值分配到内存位置。 ptr 使用指针算术,ptr1 使用数组算术(如果我可以这样称呼的话)。
在for循环结束时,ptr不指向保留内存块的第一个元素的地址,必须重新设置回来才能指向第一个元素的地址。
第二个 for 循环打印两个内存块中的数据存储。在那里,我没有将 ptr 重置为指向内存中第一个元素的地址。
现在有个大问题: 使用 free(ptr),free() 接收指向某个地址的指针(而不是保留的内存块的起始地址)。我是否理解正确,写free(ptr),我现在会释放一个不同的大小*sizeof(int)的内存块,我可能会释放一些不应该释放的敏感数据?
理解正确吗?如果是这样,在将指针与 malloc() 结合使用时,是否建议始终使用数组算术?
谢谢你, 亚历克斯
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size = 0;
printf("Enter the array size: ");
scanf("%d",&size);
int * ptr = (int *)malloc(size*sizeof(int));
int * ptr1 = (int *)malloc(size*sizeof(int));
int i = 0;
// First for loop
for( ; i<size;i++)
{
*ptr = i;
++ptr;
*(&ptr1[i]) = i;
}
ptr = ptr-size; // Resetting to the start address
// Second for loop
for(i = 0; i<size;i++)
{
printf("%d\t\t",*ptr);
ptr++;
printf("%d\n",*(&ptr1[i]));
}
free(ptr); // Is the correct memory block now freed?
free(ptr1);
return 0;
}
【问题讨论】:
-
代码更改
ptr,然后将一个有效的随机值传递给free。事后试图调整它是糟糕的设计:如有必要,保留一份副本。您必须将malloc返回的精确 值传递给free,无论哪个 变量保存它。用于获取内存的实际变量没有内存。 -
规则是你必须把它在
malloc中返回的地址给free,就是这样。如果您操纵指针使其指向其他地方,那么您的工作就是跟踪原始地址。无论您是操纵指针还是保留另一个指针,都没关系。请记住始终将free与malloc提供给您的地址相同。 -
当你试图理解这样的代码时,我发现在调试器中单步执行它并查看每一行如何更改变量、内存等很有帮助,这比看到大量 printfs 更好滚动屏幕。
标签: c pointers malloc free memory-mapped-files