2011-09-09 169 views
1

我有下面的代碼,你可以嘗試使用c99 filename.c; ./a.outrealloc有什麼問題?

#include <stdio.h> 
#include <stdlib.h> 

typedef unsigned long long int se_t; // stack element type 

se_t stack_size = 0; 
se_t *bottom_of_stack = NULL; 
#define top_of_stack (bottom_of_stack + stack_size * sizeof(se_t)) 

#define stack_infix(op) stack_push(stack_pop() #op stack_pop()) 
#define do_times(x) for(int _i=0; _i<x; _i++) 

void stack_push(se_t v) { 
    bottom_of_stack = realloc(bottom_of_stack, 
           ++stack_size * sizeof(se_t)); 
    *top_of_stack = v; 
} 

void stack_print() { 
    printf("stack(%d): \n", (int)stack_size); 
    for(se_t *i = bottom_of_stack; 
      i <= top_of_stack; 
      i += sizeof(se_t)) { 
     printf("%p: %d \n", (void*)i, (int)*i); 
    } 
} 

int main() { 
    int i = 2; 
    do_times(3) { 
     stack_push(i*=i); 
     stack_print(); 
    } 
} 

我重新分配每次我的東西推給它時間堆棧。這裏是輸出(與我的意見):

stack(1): 
0x105200820: 0 // realloc successfully allocated some memory for the first time 
0x105200860: 4 
stack(2): 
0x105200820: 0 // extended the memory range without moving it somewhere else 
0x105200860: 4 
0x1052008a0: 16 
stack(3): 
0x105200830: 0 // reallocated the memory to some other region (see the address) 
0x105200870: 0 // and failed for some reason to copy the old data! 
0x1052008b0: 0 // why?! 
0x1052008f0: 256 
+0

這可能是值得推薦的是'do_times'使用,而不只是'i_'變量'我_ ## __ LINE__'。 (個人而言,我喜歡做的事情,比如'的#define CAT_(X,Y)X ## y' /'的#define CAT(X,Y)CAT_(X,Y)'/'的#define UNIQ(x)的CAT(CAT (INTERNAL_,x),CAT(_DO_NOT_TOUCH_,__LINE __))') –

+0

'i _ ## __ LINE__'好主意!你是怎麼想出來的?它幾乎和Lisp中的gensym一樣。 – Halst

+0

我想'UNIQ(x)'是'法人'版本? – Halst

回答

2

使用此:

#define top_of_stack (bottom_of_stack + (stack_size - 1)) 

正因爲如此,你存儲數據過去的分配結束空間。

哦,改變這一行太:

i += sizeof(se_t)) { 

應該是:

i++) { 

因爲什麼pmg說一下指針運算的。

+0

這是否意味着我不需要'realloc'中的'sizeof'? – Halst

+1

不,你確實需要'realloc'的sizeof,因爲realloc的大小參數總是以字節爲單位。 –

4

指針算術已經使用sizeof (basetype)。當你做

#define top_of_stack (bottom_of_stack + stack_size * sizeof(se_t)) 

你實際上乘以sizeof (se_t)兩倍。

如果bottom_of_stack具有價值0xF000stack_size是2和sizeof (se_t)是0x10的

bottom_of_stack + stack_size == 0xF020 
bottom_of_stack + stack_size * sizeof (se_t) == 0xF400 /* or whatever */