|
sizeof и указатель на структуру! Проблема! |
|
|
|
Mar 6 2008, 10:21
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(Samodelkin @ Mar 6 2008, 12:54)  IndexDataTX = (char*) TX_x16_i2c_01; //делаем IndexDataTX указателем на структуру. Вы в этом уверены? В том что указатель ИМЕННО на структуру получили? sizeof возвращает размер того, что ей передается в качестве параметра. Если это указатель, то его размер и вернется. Если нужен размер объекта, то объект и нужно передавать. Код X = sizeof(*PTR);
|
|
|
|
|
Mar 6 2008, 10:27
|

Частый гость
 
Группа: Участник
Сообщений: 102
Регистрация: 29-05-05
Из: Днепропетровск
Пользователь №: 5 520

|
Цитата(Qwertty @ Mar 6 2008, 14:21)  Вы в этом уверены? В том что указатель ИМЕННО на структуру получили? sizeof возвращает размер того, что ей передается в качестве параметра. Если это указатель, то его размер и вернется. Если нужен размер объекта, то объект и нужно передавать. Код X = sizeof(*PTR); Да, уверен! Именно указатель на структуру я и получил, потому что что касается этого, то все работает. Но вот как сказать sizeof чтобы оно отдало размер того на что указывает указатель??????
|
|
|
|
|
Mar 6 2008, 10:37
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Samodelkin @ Mar 6 2008, 12:54)  и это ЛАЖА!!! Какая такая лажа - что спросили, то и получили - спросили размер структуры - получили размер структуры. Спросили размер указателя на char (причем именно на char а не на структуру, что впрочем все равно, хоть void ) и получли размер указателя. Цитата Но вот как сказать sizeof чтобы оно отдало размер того на что указывает указатель?????? Указатель это просто адрес. Если Вам известно, что лежит по этому адресу скажите это sizeof().
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Mar 6 2008, 10:45
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Надо было сразу привести рабочий вариант  Код struct { unsigned char KontursStatus[16]; }TX_x16_i2c_01б, *PTR;
PTR = &TX_x16_i2c_01; //делаем PTR указателем на структуру.
Buff_size = sizeof(*PTR); // Buff_size получит размер структуры
|
|
|
|
|
Mar 6 2008, 10:58
|

Частый гость
 
Группа: Участник
Сообщений: 102
Регистрация: 29-05-05
Из: Днепропетровск
Пользователь №: 5 520

|
Цитата(Qwertty @ Mar 6 2008, 14:45)  Надо было сразу привести рабочий вариант  Код struct { unsigned char KontursStatus[16]; }TX_x16_i2c_01б, *PTR;
PTR = &TX_x16_i2c_01; //делаем PTR указателем на структуру.
Buff_size = sizeof(*PTR); // Buff_size получит размер структуры У меня несколько разных структур! Чтобы обрабатывать их одной функцией, то для этого мне и нужен указатель на структуру. Так мне *PTR ставить одинаковым после каждой структуры ????? : struct { unsigned char KontursStatus[16]; }TX_x16_i2c_01, *PTR; struct { unsigned char KontursStatus[20]; }TX_x16_i2c_02, *PTR; struct { unsigned char KontursStatus[7]; }TX_x16_i2c_03, *PTR; PTR = &TX_x16_i2c_01; //делаем PTR указателем на структуру. Buff_size = sizeof(*PTR); // Buff_size получит размер структуры PTR = &TX_x16_i2c_02; //делаем PTR указателем на структуру. Buff_size = sizeof(*PTR); // Buff_size получит размер структуры PTR = &TX_x16_i2c_03; //делаем PTR указателем на структуру. Buff_size = sizeof(*PTR); // Buff_size получит размер структуры
|
|
|
|
|
Mar 6 2008, 11:26
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
То, что вы написали - не скомпилится - у вас несколько определений PTR... Если у вас несколько однотипных структур и в функциях вам нужно определять их размер - просто храните размер в первом байте структуры. Примерно так: Код struct { unsigned char size; unsigned char KontursStatus[16]; }TX_x16_i2c_01; TX_x16_i2c_01.size = sizeof(TX_x16_i2c_01); struct { unsigned char size; unsigned char KontursStatus[20]; }TX_x16_i2c_02; TX_x16_i2c_02.size = sizeof(TX_x16_i2c_02); struct { unsigned char size; unsigned char KontursStatus[7]; }TX_x16_i2c_03; TX_x16_i2c_03.size = sizeof(TX_x16_i2c_03);
void func(unsigned char *p) { unsigned char sz = *p; ... }
|
|
|
|
|
Mar 6 2008, 11:39
|

Частый гость
 
Группа: Участник
Сообщений: 102
Регистрация: 29-05-05
Из: Днепропетровск
Пользователь №: 5 520

|
Цитата(Непомнящий Евгений @ Mar 6 2008, 15:26)  То, что вы написали - не скомпилится - у вас несколько определений PTR... Если у вас несколько однотипных структур и в функциях вам нужно определять их размер - просто храните размер в первом байте структуры. Примерно так: Код struct { unsigned char size; unsigned char KontursStatus[16]; }TX_x16_i2c_01; TX_x16_i2c_01.size = sizeof(TX_x16_i2c_01); struct { unsigned char size; unsigned char KontursStatus[20]; }TX_x16_i2c_02; TX_x16_i2c_02.size = sizeof(TX_x16_i2c_02); struct { unsigned char size; unsigned char KontursStatus[7]; }TX_x16_i2c_03; TX_x16_i2c_03.size = sizeof(TX_x16_i2c_03);
void func(unsigned char *p) { unsigned char sz = *p; ... } Всем спасибо за помощь! Буду пробовать!
|
|
|
|
|
Mar 6 2008, 12:13
|
Местный
  
Группа: Свой
Сообщений: 401
Регистрация: 18-11-06
Из: Хабаровск
Пользователь №: 22 469

|
TX_x16_i2c_01, в вашем случае - это переменная типа описанной Вами структуры. IndexDataTX = (char*) TX_x16_i2c_01; // теперь вы делаете IndexDataTX указателем на эту (TX_x16_i2c_01) переменную. В первом случае , Вы действительно получаете 16, потому как получаете размер переменной. А вот во втором случае облом. Я могу ошибаться, но причина как мне кажется в том, что sizeof - это оператор времени компиляции. Во время компиляции на место него подсталяется обычное число (в чистом C89. В C99 это не так). Я очень сомневаюсь в том что факт присвоения IndexDataTX = (char*) TX_x16_i2c_01;
выясняется во время компиляции. Отсюда, компилятор просто не знает что ему подставить на место sizeof. А почему именно 2 - хз.
И кстати, как я понял, Вы пытаетесь исходя из размера переменной структуры определить функцию обработчик для переменной этой структуры. Может для 8-разрядных контроллеров это и нормально, но в общем случае, sizeof возвращает значение "как минимум". Т.е. фактический размер переменной может быть , скажем 11 байт, а в качестве размера Вы получите 16. В разных архитектурах компилятор может самолично увеличить размер структуры (то что возвращает sizeof), чтобы обеспечить выравнивание ее членов по границе. Сам я если честно с таким никогда не сталкивался (а может мало пытался?..), но всякие умные источники (Герберд Шилдт, мои товарищи) утверждают. Так что вариант, который Вам предложили в последнем посте самый правильный.
|
|
|
|
|
Mar 6 2008, 12:27
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(InvisibleFed @ Mar 6 2008, 15:13)  TX_x16_i2c_01, в вашем случае - это переменная типа описанной Вами структуры. IndexDataTX = (char*) TX_x16_i2c_01; ... Отсюда, компилятор просто не знает что ему подставить на место sizeof. А почему именно 2 - хз. IndexDataTX - переменная типа char* (указатель на char). sizeof(IndexDataTX) - это размер указателя на char - т.е. к примеру, 2 байта. sizeof(*IndexDataTX) - это размер char - т.е. 1 байт.
|
|
|
|
|
Mar 6 2008, 12:50
|

Частый гость
 
Группа: Участник
Сообщений: 102
Регистрация: 29-05-05
Из: Днепропетровск
Пользователь №: 5 520

|
Цитата(InvisibleFed @ Mar 6 2008, 16:13)  в общем случае, sizeof возвращает значение "как минимум". Т.е. фактический размер переменной может быть , скажем 11 байт, а в качестве размера Вы получите 16. В разных архитектурах компилятор может самолично увеличить размер структуры (то что возвращает sizeof), чтобы обеспечить выравнивание ее членов по границе. Сам я если честно с таким никогда не сталкивался (а может мало пытался?..), но всякие умные источники (Герберд Шилдт, мои товарищи) утверждают. Так что вариант, который Вам предложили в последнем посте самый правильный. Спасибо за ликбез! Но!!! А как тогда в "общем случае" реально вычислить размер данных в структуре? Мне например надо отправить в порт (UART например) данные из структуры, но получится что я отпарвляю одно количество байт, а там на самом деле другое!!!! И вместо недостающих данных пойдет "мусор"!!!!????
Сообщение отредактировал Samodelkin - Mar 6 2008, 12:51
|
|
|
|
|
Mar 6 2008, 13:29
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(InvisibleFed @ Mar 6 2008, 15:13)  Т.е. фактический размер переменной может быть , скажем 11 байт, а в качестве размера Вы получите 16. В разных архитектурах компилятор может самолично увеличить размер структуры (то что возвращает sizeof), чтобы обеспечить выравнивание ее членов по границе. Сам я если честно с таким никогда не сталкивался (а может мало пытался?..), но всякие умные источники (Герберд Шилдт, мои товарищи) утверждают. Так что вариант, который Вам предложили в последнем посте самый правильный. Вот именно из-за возможности выравнивания вариант с жестким указанием размера в первом поле и не годится. Изменим уровень оптимизации, поменяем компилятор, или поменяем платформу и придется во всех структурах менять это значение. У GCC еще есть возможность упаковывать структуры, с помощью ключей компиляции.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|