2015-12-11 4 views
0

Фон: Я много работаю с двоичными данными, и мне часто приходится работать с необработанными указателями. Мне также часто нужен размер, чтобы я мог проверить, читаю/списываю границы (разумно, правильно?). Теперь я пытаюсь создать синтаксический класс сахара для указателей, который содержит размер базовых данных, чтобы я мог упростить декларации функций.Причина, по которой эта ошибка reinterpret_cast падает

Демонстрация проблемы - код позади моего класса, что сбой может быть упрощена следующим образом:

char *a = (char*) malloc(4); // some underlying data 
strncpy(a, "1234", 4); // that is not statically linked so it can be written to 

uint32_t *ptr = reinterpret_cast<uint32_t*>(a); 

ptr[0] = 1234; // works 
reinterpret_cast<int&>(ptr[0]) = 1234; // curiously, this works too 
*reinterpret_cast<int*>(ptr[0]) = 1234; // this crashes the program 

printf("%d\n", ptr[0]); 

Программа выше аварий, как описано в комментариях. , Valgrind выводит следующее:

Invalid write of size 4 
    at 0x40064A: main (in /home/rr-/test) 
Address 0x4d2 is not stack'd, malloc'd or (recently) free'd 

Я подозреваю, что я нарушив строгое правило сглаживания, но:

  1. Я удостоверился использовать char* для базовой структуры. Скорее всего, это не имеет значения, потому что то, что я reinterpret_cast ing, не является char*, а uint32_t* и компилятору все равно, что uint32_t* изначально указано.
  2. Но даже если я играю с -fno-strict-aliasing и -fstrict-aliasing, программа разбивает все же ... (я компилировать программу с г ++ 5.2.0 под GNU/Linux.)

Может кто-нибудь сказать, где я сделал пойти не так, и как я могу исправить эту проблему?

+0

Что вы думаете '* reinterpret_cast (ptr [0]) = 1234;' делает? –

+0

Да, я понял это, пока я ездил на работу. Какая глупая ошибка. –

ответ

1

Вы только что сохранили 1234 в ptr[0]. Затем вы бросаете 1234 в указатель и разыгрываете его.

Это попытка доступа к адресу 1234, который не работает.

Смежные вопросы