C:malloc和free的堆栈实现

时间:2016-02-08 15:32:01

标签: c arrays pointers logical-operators comparison-operators

我正在阅读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;
}

新分配

  

allocp 0x601080

char* a = alloc(10);

之后

  

allocp 0x60108a

char* b = alloc(5);

之后

  

allocp 0x60108f

afree(b);

之后

  

allocp 0x60108f

afree(a);

之后

  

allocp 0x60108f

allocp仍然指向0x60108f。为什么不根据代码更新?

3 个答案:

答案 0 :(得分:4)

在您的代码中,通过说

a = "ayushnair";

您没有将"ayushnair" 存储到 a指向的内存中。 "ayushnair"字符串文字并说

a = "ayushnair";

您将字符串文字的基地址存储到a。这样,您实际上是通过调用alloc()来覆盖返回的指针。

这不是你想要的。您可能需要使用strcpy()将字符串文字复制到返回的指针中。

那就是说,按照当前的代码,稍后再通过调用

afree(b);
afree(a);

当你试图指向不指向同一个对象的指针时,你正在调用undefined behavior

引用C11,章节§6.5.8,关系运算符

  

比较两个指针时,结果取决于相对位置   指向的对象的地址空间。如果两个指向对象类型的指针都指向   相同的对象,或两者都指向同一个数组对象的最后一个元素,它们   比较平等。如果指向的对象是同一聚合对象的成员,   稍后声明的结构成员的指针比指向成员的指针要大   在结构中先前声明,并指向具有较大下标的数组元素   值比具有较低下标值的同一数组的元素的指针大。指向同一个union对象的成员的所有指针都比较相等。如果   表达式P指向数组对象的元素,表达式Q指向   同一个数组对象的最后一个元素,指针表达式Q + 1比较大于   P. 在所有其他情况下,行为未定义。

答案 1 :(得分:2)

char* a = alloc(10);

这&#34;分配&#34;来自allocbuf的内存,并将指向该内存的指针分配给a

a = "ayushnair";

这会指定一个不同的指向a的指针 - 指向字符串文字"ayushnair"不在allocbuf 但完全在记忆中的其他地方。

从现在开始,你的程序越来越混乱(特别是因为你在b犯了类似的错误)。对afree( a )的调用没有任何意义,因为a不再指向alloc()返回的内容,afree()进行的比较实际上调用了未定义的行为,正如Sourav Ghosh指出的那样 - - 但错误是a = "ayushnair"(以及与b类似的分配)。

语言C没有&#34;字符串对象&#34;的概念,只是指向以char结尾的'\0'序列的指针被称为&# 34;串&#34;并有一些支持功能。运算符=的合适定义表示&#34;复制内容&#34; 是这些支持功能的一部分。

想要做的事情是:

char * a = alloc( 10 );
strcpy( a, "ayushnair" );

复制从字符串文字复制到 a指向的内存。

所以,最重要的是,你的问题不是关于逻辑或比较运算符,而是关于数组 - 关于指针和字符串。我希望我能够澄清一点。

答案 2 :(得分:-2)

它没有更新指针(在afee上),因为这个记忆分配器的算法是渐进的并且具有预先分配的内存部分的“无记忆”。因此只返回指向未使用内存的指针。分配ALLOCSIZE后,将无法分配更多的mem。大多数内存分配器都会对消耗的内存做出一些假设。