указатели — reinterpret_cast в переполнении стека

 uint32_t r,g,b;
r = (uint32_t)145;
g = (uint32_t)131;
b = (uint32_t)139;
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
float rgbf = *reinterpret_cast<float*>(&rgb);

uint32_t rgbnew = *(reinterpret_cast<uint32_t *>(&rgbf));
uint8_t rnew = (rgbnew >> 16) & 0x0000ff;
uint8_t gnew = (rgbnew >> 8) & 0x0000ff;
uint8_t bnew = (rgbnew) & 0x0000ff;

Когда я пытаюсь запустить этот код, возникает ошибка сегментации в строке

uint32_t rgb = ((uint32_t) r << 16 | (Uint32_t) г << 8 | (Uint32_t) б);

На самом деле, в одном месте все работает нормально. В другом месте это дает ошибку.

-2

Решение

Пожалуйста, попробуйте скомпилировать ваш код со всеми предупреждениями и отладочной информацией (например, с g++ -Wall -g в Linux) и улучшать его до тех пор, пока не будут выданы предупреждения. Научитесь пользоваться отладчиком (т.е. gdb в Linux)

Я предполагаю, что ошибка, вероятно, в

 float rgbf = *reinterpret_cast<float*>(&rgb);

потому что это может вызвать ошибку, если rgb (Т.е. uint32_t) а также float не имеют одинаковые ограничения выравнивания или размера. Некоторые системы (процессоры, ABI, компиляторы) могут иметь разные & несовместимые ограничения для них.


Кстати, ваш код хорошо работает с GCC 4.7 в Debian / GNU / Linux / x86-64, который вызывается как

   g++-4.7 -std=c++11 -Wall -g ramji.cc -o ramji

когда у меня есть

 #include <cstdint>
#include <iostream>

int main(int argc, char**argv)
{
uint32_t r,g,b;
r = (uint32_t)145;
g = (uint32_t)131;
b = (uint32_t)139;
std::cout << "r=" << r << " g=" << g << " b=" << b << std::endl;
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
std::cout << "rgb=" << rgb << std::endl;
float rgbf = *reinterpret_cast<float*>(&rgb);
std::cout << "rgbf=" << rgbf << std::endl;
uint32_t rgbnew = *(reinterpret_cast<uint32_t *>(&rgbf));
std::cout << "rgbnew=" << rgb << std::endl;
uint8_t rnew = (rgbnew >> 16) & 0x0000ff;
uint8_t gnew = (rgbnew >> 8) & 0x0000ff;
uint8_t bnew = (rgbnew) & 0x0000ff;
std::cout << "rnew=" << rnew << " gnew=" << gnew
<< " bnew=" << bnew << std::endl;
return 0;
}

Нет предупреждений, нет сбоев при исполнении.

Заметить, что <cstdint> требует C ++ 11 соответствующий компилятор.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]