2011-09-09 4 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_'の代わりに 'i _ ## __ LINE__'変数を使うことをお勧めします。 (個人的には、#define CAT_(x、y)x ## y'/'#define CAT(x、y)CAT_(x、y)'/'#define UNIQ (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'のsize引数は常にバイトであるため、' realloc'には 'sizeof'が必要です。 –

4

ポインタ演算は、すでにsizeof (basetype)を使用しています。あなたがするとき

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

あなたは効果的にsizeof (se_t)を2倍しています。

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 */ 
関連する問題