2012-05-11 1 views
3

Plain C, on Windows 7 & HP машина.Указатель смещения не работает в memset?

int main(void) { 

    unsigned int a = 4294967295; 
    unsigned int *b = &a; 

    printf("before val: '%u'\n", *b); // expect 4294967295, got 4294967295 

    memset(b+2, 0, 1); 

    printf("after val: '%u'\n", *b); 
    // little endian   4th  3rd  2nd  1st 
    // expect 4278255615 - 11111111 00000000 11111111 11111111 
    // got 4294967295 - 11111111 11111111 11111111 11111111 

    return 0; 

} 

Я хочу установить третий байт целого числа в 0x0, но остается тем же. Есть идеи? Спасибо.

На моей машине int 32 бит.

ответ

7

Смещение/вычитание указателя не перемещается только одним байтом - оно перемещается по размеру типа объекта, на который указывают.

То есть (при условии, 4-байтовые целые),

int *p = 0x00004 
int *q = p+1; 
assert(q == 0x00008) 

В принципе, это то же самое, как если бы вы использовали индекс оператора:

int *q = &p[1] 

Если вы хотите прирастить указатель одним, отбросить его до unsigned char *. Как вы это делали, вы переписывали память, которая не была частью переменной a и, возможно, переписывала существующие данные для чего-то еще.

+1

На самом деле, вы не можете ничего о '(Int *) предположим, 0 + 1 'за исключением того, что это'! = 0', так как нулевой указатель могут быть обработаны специально. –

+0

@larsmans bah humbug: P Вы не можете предположить, что NULL равно нулю: P Но я изменил свой пост. Привет, помощник. –

+0

Правильно, он увеличивается по размеру. Полный goof. Спасибо. Примите через минуту. – jn1kk

2

b + 2 meens фактически смещение двух int не двух байтов.

unsigned int *b = &a; 
memset(b+2, 0, 1); 

На самом деле вы хотите изменить третий байт

unsigned int *b = &a; 
memset(((char*)b)+2, 0, 1); 
0

ИНТ только гарантированно будет по крайней мере, два байта, так что если вы хотите установить третий байт следует использовать длинные Int (или uint32_t). Во всяком случае, я хотел бы сделать это с помощью побитового оператора и

unsigned long a = 4294967293; 
/* regular code */ 
a &= 0xFFFF00FF;