История изменений
Исправление LINUX-ORG-RU, (текущая версия) :
Здрасти девушка, как дила!
Смотри что может тут пойти не так и почему тигр прав.
Вот у тебя unsigned long = uint32_t
значение равное 70536
(этому зачению нужно больше 2х байт) лежит по указателю *p
теперь ты АХТУНГ сначала кастуешь указатель к uint16_t
тем самым отрезаешь 2 байта от арифметики затем плюсуешь i
значение коророго равно например 10. И теперь вместо прохождения по массиву на (sizeof(uint32_t) * i = 40 ) байт ты пройдёшь (sizeof(uint16_t) * i = 20) байт. Тоесть ты тупо во первых не на тот индекс данных попадёшь, во вторых лежащее там значение будет вообще мусором ибо обрежется и втретьих там вообщзе изначально может лежать значение которое в uint16_t
не влезет и будет его кольцевое переполнение и ты опять получишь белиберду вместо ожидаемого числа. И тут вообще дело не в размере указателя.
Нужно так
uint16_t buff = 0;
unsigned int value = 0;
/*
Сначала выясним у нас индекс в космос не улетел
*/
if(i <= P_ARRAY_SIZE)
{
value = *(p+i);
}else{
ругаемся
}
/*или просто value = *(p + (i % P_ARRAY_SIZE)) если допустимо*/
/*
сначала узнаём влезет ли вообще значение int в short.
для этого сначала переходим на нужный индекс указателя
разыменовываем его и сравниваем с лимитом типа в который будем писать
*/
if(value <= USHRT_MAX)
{
/*и только теперь как белые люди спокойно кастуем и то каст что-бы не ругался компилёр*/
htonh((uint16_t)value);
}else{
fprintf(stderr,"overflow uint16_t %s:%d:%s\n"__FILE__,__LINE__,__func__);
....
}
Или короче, если ты уверена в i
уверена в значени массива p
uint16_t buff = *(p+i);
htonh(buff);
ну или сосем htonh((uint16_t)*(p+i))
коротко. Сначала двигаешь, адрес с учётом арифметики инта а не шорта, затем разыменовываешь значние и кастуешь его к шорту. Если А значение влезает 100% Б спещение по индексу p
проверено выше.
Исправление LINUX-ORG-RU, :
Здрасти девушка, как дила!
Смотри что может тут пойти не так и почему тигр прав.
Вот у тебя unsigned long = uint32_t
значение равное 70536
(этому зачению нужно больше 2х байт) лежит по указателю *p
теперь ты АХТУНГ сначала кастуешь указатель к uint16_t
тем самым отрезаешь 2 байта от арифметики затем плюсуешь i
значение коророго равно например 10. И теперь вместо прохождения по массиву на (sizeof(uint32_t) * i = 40 ) байт ты пройдёшь (sizeof(uint16_t) * i = 20) байт. Тоесть ты тупо во первых не на тот индекс данных попадёшь, во вторых лежащее там значение будет вообще мусором ибо обрежется и втретьих там вообщзе изначально может лежать значение которое в uint16_t
не влезет и будет его кольцевое переполнение и ты опять получишь белиберду вместо ожидаемого числа. И тут вообще дело не в размере указателя.
Нужно так
uint16_t buff = 0;
unsigned int value = 0;
/*
Сначала выясним у нас индекс в космос не улетел
*/
if(i <= P_ARRAY_SIZE)
{
value = *(p+i);
}else{
ругаемся
}
/*или просто value = *(p + (i % P_ARRAY_SIZE)) если допустимо*/
/*
сначала узнаём влезет ли вообще значение int в short.
для этого сначала переходим на нужный индекс указателя
разыменовываем его и сравниваем с лимитом типа в который будем писать
*/
if(value <= USHRT_MAX)
{
/*и только теперь как белые люди спокойно кастуем и то каст что-бы не ругался компилёр*/
htonh((uint16_t)value);
}else{
fprintf(stderr,"overflow uint16_t %s:%d:%s\n"__FILE__,__LINE__,__func__);
....
}
Исходная версия LINUX-ORG-RU, :
Здрасти девушка, как дила!
Смотри что может тут пойти не так и почему тигр прав.
Вот у тебя unsigned long = uint32_t
значение равное 70536
(этому зачению нужно больше 2х байт) лежит по указателю *p
теперь ты АХТУНГ сначала кастуешь указатель к uint16_t
тем самым отрезаешь 2 байта от арифметики затем плюсуешь i
значение коророго равно например 10. И теперь вместо прохождения по массиву на (sizeof(uint32_t) * i = 320 ) байт ты пройдёшь (sizeof(uint16_t) * i = 160) байт. Тоесть ты тупо во первых не на тот индекс данных попадёшь, во вторых лежащее там значение будет вообще мусором ибо обрежется и втретьих там вообщзе изначально может лежать значение которое в uint16_t
не влезет и будет его кольцевое переполнение и ты опять получишь белиберду вместо ожидаемого числа. И тут вообще дело не в размере указателя.
Нужно так
uint16_t buff = 0;
unsigned int value = 0;
/*
Сначала выясним у нас индекс в космос не улетел
*/
if(i <= P_ARRAY_SIZE)
{
value = *(p+i);
}else{
ругаемся
}
/*или просто value = *(p + (i % P_ARRAY_SIZE)) если допустимо*/
/*
сначала узнаём влезет ли вообще значение int в short.
для этого сначала переходим на нужный индекс указателя
разыменовываем его и сравниваем с лимитом типа в который будем писать
*/
if(value <= USHRT_MAX)
{
/*и только теперь как белые люди спокойно кастуем и то каст что-бы не ругался компилёр*/
htonh((uint16_t)value);
}else{
fprintf(stderr,"overflow uint16_t %s:%d:%s\n"__FILE__,__LINE__,__func__);
....
}