2016-02-02 17 views
1

我有一個stucture這兩個地址如何可以有所不同?

typedef struct s_block 
{ 
    size_t   size; 
    struct s_block *next; 
    struct s_block *back; 
    int    free; 
    void   *data; 
}     t_block; 

我初始化這樣說:

int  createHeader() 
{ 
    void *data; 
    data = sbrk(BLOCK_SIZE + (sizeof(t_block) * 2)); 
    header = data; 
    header->next = header; 
    header->back = header; 
    header->size = 0; 
    createNewBlock(data + sizeof(t_block), BLOCK_SIZE + sizeof(t_block), 0); 
    return 0; 
} 

void *createNewBlock(void *beginAddress, size_t size, int free) 
{ 
    printf("%d\n", size); 
    t_block *newBlock; 
    printf("first %p\n", beginAddress); 
    printf("addr : %p\n", beginAddress + size); 
    newBlock = beginAddress; 
    newBlock->back = header->back; 
    newBlock->next = header; 
    newBlock->size = size; 
    newBlock->free = free; 
    newBlock->data = beginAddress + sizeof(t_block); 
    header->back->next = newBlock; 
    header->back = newBlock; 
    header->size++; 
    show_alloc_mem(); 
    return newBlock->data; 
} 

當我在createNewBlock顯示beginAddress,給出的地址是好的,當我顯示beginAddress + size的ADRESS,它給我正確的地址:

140 
first 0x18f9028 
addr : 0x18f90b4 

但是當我輸入我的功能show_alloc_mem()

void show_alloc_mem() 
{ 
    t_block *tmp; 

    tmp = header->next; 
    printf("break : %p\n", header); 
    while (tmp != header) 
    { 
    if (tmp->free == 1) 
     printf("%p - %p : %d bytes\n", tmp, tmp + tmp->size, (int)tmp->size); 
    else 
     printf("free: %p - %p : %d bytes\n", tmp, tmp + tmp->size, (int)tmp->size); 
    tmp = tmp->next; 
    } 
} 

發生了奇怪的行爲。 標題地址和tmp地址是正確的。但是tmp + size的地址不是。

break : 0x18f9000 
free: 0x18f9028 - 0x18fa608 : 140 bytes 

你知道爲什麼嗎?

+3

你有沒有注意到新的區別*正好是* 40 * 140? –

回答

3

您正在執行指針算術,期望它的行爲與整數算術類似。

表達tmp + tmp->size因爲要添加的整數(tmp->size)的指針的結構(tmpt_block*類型的)的計算結果爲(int)tmp + sizeof(t_block)*((int)tmp->size)

+0

IOW,在添加之前,要添加的數字乘以目標指針的值類型的sizeof。 (這應該是指針算術的任何介紹性文本的基本特徵,我希望。) –

+0

好的,謝謝我現在明白了。所以我通過將我的tmp變量轉換爲void * –

+1

@DimitriDanilov來解決這個問題 - 這將與GCC和其他一些編譯器一起工作,但是不是標準的,因爲標準C不支持'void *'指針的算術運算。您可以使用'char *'代替標準,儘管這可能需要在代碼中更明確地指針類型轉換。 –

2

您使用兩個不同的指針運算:

  • 一個與void *
  • 一個與t_block *

你的編譯器允許你做void *算術,但它是從標準排除在外。某些編譯器(您的)在void *上使用自然算術,所以在第一個表達式中,它計算BaseAdressValue+size,而在第二個表達式中BaseAddressValue+40*size(40是結構的大小,5個8字節指針,您位於64位指針平臺上) 。

相關問題