2011-09-09 167 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 */