当指针未知时,如何在C中释放内存?
我希望释放没有指针的内存块。在我的程序中,我依次调用当指针未知时,如何在C中释放内存?,c,pointers,memory,memory-management,C,Pointers,Memory,Memory Management,我希望释放没有指针的内存块。在我的程序中,我依次调用malloc,希望由malloc(1),malloc(4),malloc(5)创建的内存是连续的。然后,当我只有指向malloc(5)的指针时,释放这些内存。但我想不出怎么能做到这一点;我不能简单地创建一个指向ptr[-5]地址的指针,然后释放5字节的内存?如何做到这一点 #include <string.h> #include <stdio.h> #include <stdlib.h> int main
malloc
,希望由malloc(1)
,malloc(4)
,malloc(5)
创建的内存是连续的。然后,当我只有指向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);
}
#包括
#包括
#包括
int main(){
malloc(1);
malloc(4);
char*ptr=malloc(5);
免费(ptr);
}
免费(无效*)
[解除分配]先前通过调用malloc
、calloc
或realloc
分配的内存块被解除分配,使其再次可用于进一步分配
如果ptr未指向与上述函数一起分配的内存块,则会导致未定义的行为。
-
没有办法
但我想不出怎么能做到这一点
那是因为这是不可能的。从malloc
返回的块可以以真正任意的顺序出现。释放动态分配内存块的唯一方法是让程序可以访问指向它的指针。其他任何东西都是未定义的行为
注意:实现
malloc
执行“簿记”以确定要释放的块类型。虽然破解它们的实现并非不可能,但没有办法以标准兼容、可移植的方式来实现。由于各种原因,您无法创建[-5]…东西,但从实际角度来看,您必须记住,分配给malloc()
的内存是从堆中出来的,而不是从堆栈中出来的从其他地方对它进行“计数”是困难的(因为对malloc的多次调用不能保证是连续的)
如果指针在未被释放的情况下失去与内存的关联(或超出范围),则称为内存泄漏,如果没有C语言中不可用的穷举技术(例如Java的标记/清除垃圾收集,或对整个内存进行mallocing并扫描它或其他),则无法回收该内存
因此,当指针未知时,您无法在C中释放内存。这绝不是对您所做工作的认可,但如果您知道块是连续分配的,则有可能
#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));
}
例如:
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));
}
#定义汇总(数字,倍数)(((数字+倍数-1)/倍数)*倍数)
#定义偏移量(大小)((大小<24)?32:汇总(大小+8,16))
int main(int argc,char*argv[]){
字符*ptr1,*ptr2,*ptr3;
ints1=atoi(argv[1]);
int s2=atoi(argv[2]);
ints3=atoi(argv[3]);
ptr1=(char*)malloc(s1);
ptr2=(char*)malloc(s2);
ptr3=(char*)malloc(s3);
fprintf(标准输出,“%p%p%p\n”、ptr1、ptr2、ptr3);
断言(ptr3==(ptr2+偏移量(s2));
断言(ptr2==(ptr1+OFFSET(s1));
//尝试从ptr3构造ptr2。
免费(ptr3);
自由(ptr3偏移量(s2));
自由(ptr3偏移(s2)-偏移(s1));
}
你不能做你想做的事。你甚至不应该尝试做你想做的事
即使您准确地计算出malloc()在做什么,您的程序也将依赖于未定义的行为。当新版本的C库出现时,行为可能会发生变化,如果您使用不同的工具链编译程序(从GNU C切换到Microsoft C或其他任何工具),您的程序几乎肯定会失败
任何时候分配内存时,都需要跟踪指针。如果程序甚至不知道内存,就无法释放它
跟踪内存分配。如果要设计动态分配的数据结构,则设计应包括跟踪这些结构的功能,例如在链接列表中保留地址列表或其他内容
如果这看起来是一个很大的工作,也许考虑使用像C语言或java或Python之类的托管语言。首先,你似乎不理解<代码> MalOC/<代码>如何工作。将连续的数字传递给<代码> MalOC/
void* malloc (size_t size);
int* myDynamicArray = malloc(sizeof(int)*numberOfElements);
void free (void* ptr);
虽然整数可以转换为大小\u t
,但它仍然是分配的字节数,而不是元素数。如果要分配数组,请按如下操作:
void* malloc (size_t size);
int* myDynamicArray = malloc(sizeof(int)*numberOfElements);
void free (void* ptr);
然后,您可以通过执行以下操作来访问元素:
int i;
for(i=0;i<numberOfElements;i++)
printf("%d",myDynamicArray[i]);
free(myDynamicArray);
你可以简单地称之为:
int i;
for(i=0;i<numberOfElements;i++)
printf("%d",myDynamicArray[i]);
free(myDynamicArray);
为什么你要在野外这样进行malloc呢?为什么?为什么?如果你想要连续的内存,只需调用
malloc
并执行一些指针运算就可以分配它。这只会导致未定义的行为。希望内存分配是连续的似乎很乐观:)看起来你可能想要一些这里的事情很有趣,但是