[英]How can I free memory in C when a pointer is not known?
我希望释放没有指针的内存块。 在我的程序中,我顺序调用malloc
,希望由malloc(1)
, malloc(4)
和malloc(5)
创建的malloc(1)
是连续的。 然后,当我只有指向malloc(5)
的指针时,就释放这些内存。 但是我想不起来怎么做。 我不能简单地创建一个指向ptr [-5]地址的指针,然后释放5个字节的内存吗? 如何才能做到这一点?
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
malloc(1);
malloc(4);
char* ptr = malloc(5);
free(ptr);
}
您无法做自己想做的事。 您甚至都不应该尝试做您想做的事。
即使您确切地知道malloc()
在做什么,程序也将依赖于未定义的行为。 当新版本的C库到来时,行为可能会更改,并且如果使用其他工具链(从GNU C切换到Microsoft C或其他工具)进行编译,则程序几乎肯定会失败。
任何时候分配内存时,都需要跟踪指针。 如果您的程序甚至不知道内存,则无法释放它。
跟踪您的内存分配。 如果要设计要动态分配的数据结构,则设计应包括跟踪它们的功能,例如将地址列表保存在链接列表中或其他内容中。
如果这看起来需要大量工作,则可以考虑使用托管语言,例如C#或Java或Python或其他任何语言。
free(void*)
[deallocate]先前由对
malloc
,calloc
或realloc
的调用分配的一块malloc
被释放,使其再次可用于进一步的分配。如果ptr不指向分配有上述功能的内存块,则会导致未定义的行为 。 -http://www.cplusplus.com/reference/cstdlib/free/
不可能。
但我想不到如何做到这一点
那是因为不可能。 从malloc
获得的块可以按任意顺序出现。 释放动态分配的内存块的唯一方法是使程序可以访问它的指针。 其他都是未定义的行为。
注意: malloc
实现执行“簿记”,以查明要释放的块类型。 尽管入侵它们的实现并非不可能,但没有办法以符合标准的,可移植的方式来实现。
出于多种原因,您无法创建[-5] ...事物,但是从实际的角度出发,您必须记住,使用malloc()
分配的malloc()
正在从堆中移出,而不是从堆栈中移出,以便“计数”为从其他地方很难做到这一点(因为不能保证对malloc的多次调用是顺序的)。
当指针在没有释放的情况下失去与内存的关联(或超出范围)时发生的事情称为内存泄漏,并且没有C中不易使用的详尽技术(例如Java的标记/清除垃圾收集,或m分配整个内存和扫描它或其他东西)无法回收此内存。
因此,当指针未知时,您将无法释放C中的内存。
这绝不是对您所做工作的认可,但是可以假设您知道块是连续分配的 。
例如:
int main(){
char* ptr1=malloc(1);
char* ptr2=malloc(4);
char* ptr3=malloc(5);
// Verify that the memory is in fact continuous.
assert(ptr3==(ptr2+4));
assert(ptr3==(ptr1+5));
free(ptr3); // Frees 5 bytes at ptr3
free(ptr3-4); // Frees 4 bytes at ptr2
free(ptr3-5); // Frees 1 byte at ptr1
}
因此,如果您有一个指针,并且知道在该指针之前分配了一组连续字节的事实,则可以使用指针算术简单地偏移指针。 它非常危险,不建议使用,但有可能。
编辑:
我运行了一个测试程序,并在我的体系结构上以32个字节的块分配了内存,因此ptr1 + 32 == ptr2和ptr2 + 32 = ptr3。 它对小于或等于24个字节的任何块执行此操作。 因此,如果我分配了24个或更少的内容,则每个ptr将比前一个大32个字节。 如果我分配了25个或更多,那么它又分配了16个字节,总共48个。
因此,在我的体系结构中,您将需要在如何使用指针算术生成指针方面更具创造力,因为它无法按预期工作。
这是一个示例程序,可在我的体系结构上适用于所有大小的ptr1,ptr2和ptr3。
#define ROUNDUP(number, multiple) (((number + multiple -1)/multiple)*multiple)
#define OFFSET(size) ((size < 24) ? 32 : ROUNDUP(size+8,16))
int main(int argc, char* argv[]){
char* ptr1, *ptr2, *ptr3;
int s1=atoi(argv[1]);
int s2=atoi(argv[2]);
int s3=atoi(argv[3]);
ptr1=(char*)malloc(s1);
ptr2=(char*)malloc(s2);
ptr3=(char*)malloc(s3);
fprintf(stdout, "%p %p %p\n", ptr1, ptr2, ptr3);
assert(ptr3==(ptr2+OFFSET(s2)));
assert(ptr2==(ptr1+OFFSET(s1)));
// Try to construct ptr2 from ptr3.
free(ptr3);
free(ptr3-OFFSET(s2));
free(ptr3-OFFSET(s2)-OFFSET(s1));
}
首先-似乎您不了解malloc
工作原理-将连续数字传递给malloc
, 不会使它分配数组。 malloc
的定义如下:
void* malloc (size_t size);
虽然可以将整数转换为size_t
,但它仍然是分配的字节数,而不是元素号。 如果要分配数组,请执行以下操作:
int* myDynamicArray = malloc(sizeof(int)*numberOfElements);
然后,您可以通过执行以下操作访问元素:
int i;
for(i=0;i<numberOfElements;i++)
printf("%d",myDynamicArray[i]);
然后,就像其他人指出的那样-您可以通过调用free
函数来释放内存。 free
定义如下:
void free (void* ptr);
您只需执行以下操作即可调用它:
free(myDynamicArray);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.