[英]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.