[英]C: Stack implementation of malloc and free
我正在阅读K&R指针5.4节,其中完成了malloc()
和free()
的堆栈实现。 我正在使用gdb调试代码,并且alloc()
部分按预期工作。 但是对于afree()
部分,指针仍然指向与以前相同的位置。 这是代码:
#include <stdio.h>
#define ALLOCSIZE 10000
static char allocbuf[ALLOCSIZE];
static char* allocp = allocbuf;
char* alloc(int n)
{
if(allocbuf + ALLOCSIZE - allocp >= n)
{
allocp += n;
return (allocp - n);
}
else
return 0;
}
void afree(char* p)
{
if(p >= allocbuf && p < allocbuf + ALLOCSIZE)
allocp = p;
}
int main()
{
char* a = alloc(10);
a = "ayushnair";
char*b = alloc(5);
b = "snea";
printf("%p %p\n", a, b);
afree(b);
afree(a);
printf("%p %p\n", a, b);
return 0;
}
新分配
分配0x601080
在char* a = alloc(10);
分配0x60108a
在char* b = alloc(5);
分配0x60108f
afree(b);
分配0x60108f
afree(a);
分配0x60108f
allocp
仍指向0x60108f
。 为什么不根据代码更新?
在您的代码中,通过说
a = "ayushnair";
你不存储"ayushnair"
成指向的内存a
。 "ayushnair"
是字符串文字 , "ayushnair"
a = "ayushnair";
要存储的字符串的基地址字面成a
。 这样,您实际上将通过调用alloc()
覆盖返回的指针。
这不是您想要的东西。 您可能需要使用strcpy()
将字符串文字复制到返回的指针中。
也就是说,按照当前代码,稍后通过调用
afree(b);
afree(a);
您在尝试比较未指向同一对象的指针时正在调用未定义的行为 。
引用C11
,第§6.5.8章, 关系运算符
比较两个指针时 ,结果取决于所指向对象的地址空间中的相对位置。 如果两个指向对象类型的指针都指向同一对象,或者都指向同一数组对象的最后一个元素,则它们的比较相等。 如果所指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针大于指向早于结构中声明的成员的指针,指向具有较大下标值的数组元素的指针大于指向同一数组的元素的指针下标值较低。 指向同一联合对象的成员的所有指针比较相等。 如果表达式P指向数组对象的元素,而表达式Q指向同一数组对象的最后一个元素,则指针表达式Q + 1比较大于P。 在所有其他情况下,该行为是不确定的。
char* a = alloc(10);
这种从“分配”存储器allocbuf
,指针到该存储器分配给a
。
a = "ayushnair";
这种分配不同的指针指向a
-一个指向字符串常量"ayushnair"
, 这是不是在allocbuf
,但其他地方完全在内存中。
从现在开始,您的程序越来越混乱(特别是因为您对b
犯了类似的错误)。 对afree( a )
的调用没有意义,因为a
不再指向返回的alloc()
,并且如Sourav Ghosh所指出的那样,由afree()
完成的比较实际上会调用未定义的行为-但错误是a = "ayushnair"
(以及与b
相似的赋值)。
语言C没有“字符串对象”的概念,只是一个约定,即以'\\0'
结尾的char
序列的指针称为“字符串”,并具有一些支持功能。 运算符=
合适定义是“复制内容”, 不属于那些支持功能。
您想做的是:
char * a = alloc( 10 );
strcpy( a, "ayushnair" );
这会从字面到内存指向的字符串复制 a
。
因此,最重要的是,您的问题与逻辑运算符或比较运算符无关,与数组无关,而与指针和字符串有关。 我希望我能澄清一下。
由于内存分配器的此算法是渐进式的,并且不具有先前分配的内存部分的“无内存”,因此它不会更新指针。 因此,仅返回指向未使用内存的指针。 分配ALLOCSIZE之后,将无法分配更多的内存。 大多数内存分配器都对消耗的内存做出一些假设。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.