проблема структуры c - PullRequest
       3

проблема структуры c

3 голосов
/ 07 октября 2010

спасибо за вашу поддержку в решении моих предыдущих проблем. Сейчас я изучаю самостоятельные ссылочные структуры. Я написал следующий код:

#include <stdio.h>

int main()
{
system("clear");
struct node
{
 int x;
  struct node *next;
} p1;

printf(" \nthe address of node1 = %u",& p1);

printf(" \n\nthe size of node 1 = %d",sizeof( p1));
printf("\n\n the size of info part = %d",sizeof(p1.x));
printf("\n\n the size of pointer part = %ld",sizeof(p1.next));
printf("\nthe size of node is = %d\n",sizeof(struct node));
return;
}

Программа скомпилирована с несколькими предупреждениями, такими как:

предупреждение: формат ‘% u’ ожидает тип "Unsigned int", но аргумент 2 имеет тип ‘struct node *’

Каждый раз, когда я что-то делаю с указателем, генерируется такое предупреждение. В чем проблема? Я этого не знаю Кто-нибудь может объяснить, почему это происходит в Linux (особенно)?

Мой второй вопрос: когда я запускаю программу, она показывает размер структуры 16, тогда как int принимает 4 байта (Ubuntu 10) и указатель имеет 8 байтов. Тогда почему он показывает размер структуры 16 байт?

Ответы [ 4 ]

4 голосов
/ 07 октября 2010

В C99 используйте '%zd', чтобы напечатать size_t.

В другом месте, просто приведите результат от sizeof() к int;вы не собираетесь ничего переполнять.

Для печати указателей в C99, если вам не нравится формат по умолчанию из %p:

#include <inttypes.h>

printf("Pointer = 0x%" PRIXPTR "\n", (uintptr_t)&something);

Тип uintptr_tгарантированно будет достаточно большим, чтобы содержать указатели.

И ваш размер проблемы из-за требований выравнивания;8-байтовые указатели должны быть выровнены по 8 байтам для оптимальной производительности (на некоторых машинах, чтобы избежать сбоев).Таким образом, структура должна быть кратна 8 байтам, а 16 - это наименьшее кратное 8, которое больше 12 байт.У вас также будет некоторый отступ между двумя частями вашей структуры - фактически 4 байта заполнения.Вы можете использовать макрос offsetof() из <stddef.h>, чтобы продемонстрировать это.

0 голосов
/ 07 октября 2010

Эта программа отлично работает под дистрибутивом LINUX Fedora12.Это дает правильный вывод.

0 голосов
/ 07 октября 2010

Многие архитектуры ЦП не могут обрабатывать или очень неэффективны при обработке произвольных адресов.

Ваша архитектура, которую я предполагаю x86_64, хочет получить доступ к памяти, по крайней мере, из 8 байтовых блоков.

Итак, 12 байтов равны полутора 8-байтовым фрагментам - не очень хорошо.Затем происходит следующее: компилятор дополняет структуру фиктивными данными в конце до тех пор, пока он не уместится даже в 8 байтных блоков, в данном случае это 4 дополнительных байта, что в сумме составляет 16 байт.

То же самое касаетсяразные процессоры, но с разными выравниваниями.Некоторые процессоры даже работают без выравнивания вообще, но большинство современных процессоров работают лучше с выравниванием.

Как уже отмечали другие, используйте, например,% p для печати указателя.

Для size_tprintfs, используйте %lu и приведите к (unsigned long), если вы не можете использовать C99 и %zd.

0 голосов
/ 07 октября 2010

%p - это строка формата для указателя, которую вы передаете первой printf.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...