memcpy
не выделяет никакой памяти. В вашем вызове memcpy
память для адресата arr
была выделена, когда была определена переменная arr
(char arr[400]
).
Там есть проблема, которая заключается в том, что вы не выделили достаточно места. Вы копируете sizeof(updata)
байтов в arr
, что, вероятно, 1 + 4 + 7 * 256 = 1797 (это может различаться в зависимости от sizeof(int)
и от того, действительно ли __packed__
не использует все неиспользуемые байты на вашей платформе). Если вам действительно нужно arr
(вы, вероятно, нет), сделайте его как минимум sizeof(updata)
большим. Определение его char arr[sizeof(updata)]
в порядке.
Если макет структуры определен каким-либо внешним форматом, вы должны использовать тип фиксированного размера вместо int
(который составляет 2 или 4 байта в зависимости от платформы и может быть других размеров, но вы вряд ли чтобы встретить их).
Если макет структуры определен каким-то внешним двоичным форматом, и вы хотите распечатать 1797 байт в этом формате, используйте fwrite
.
fwrite(updata, sizeof(updata), 1, stdout);
Если вы хотите иметь человеческое представление данных, используйте printf
с соответствующими спецификациями формата.
printf("ip='%c' udp=%d\n", updata.ip, updata.ip);
for (i = 0; i < sizeof(updata.rules)/sizeof(updata.rules[0]); i++) {
puts(updata.rules[i].myname);
}
Несмотря на название, char
фактически тип байтов. Для символов в C. не существует отдельного типа. Символьная константа, такая как 'a'
, фактически является целым значением (97 почти для всех систем, согласно ASCII). Это похоже на запись putchar
или printf("%c", …)
, которые делают байт интерпретированным как символ.
Если ваш компилятор не сигнализирует об ошибке, когда вы смешиваете вверх указатель (например, char*
) с целым числом, с другой стороны, повернуть вверх уровень предупреждения. С Gcc используйте как минимум gcc -O -Wall
.
После фактически компиляции кода, я вижу основную ошибку (вы должны иметь копию вставили сообщение об ошибке от компилятора в вашем вопросе):
udpdata.rules[0].myname = "lalla\0" ;
udpdata.rules[0].myname
представляет собой массив байтов. Вы не можете назначить массив на C. Вам нужно скопировать элементы по одному. Поскольку это массив из char
, и вы хотите скопировать в него строку, вы можете использовать strcpy
для копирования всех байтов строки. Для кучи байтов в целом вы должны использовать memcpy
.
strcpy(udpdata.rules[0].myname, "lalla");
(Обратите внимание, что "lalla\0"
эквивалентно "lalla"
, все строковые литералы нулем в C.¹) Поскольку strcpy
не выполняет проверку размера, вы должны убедиться, что строка (в том числе его завершающего нулевого символа) помещается в память, которую вы выделили для целей. Вы можете использовать другие функции, такие как strncat
или strlcpy
, если вы хотите указать максимальный размер.
¹ Существует одно исключение (и только это исключение), где "lalla"
не будет иметь нулевое завершение: при инициализации массива из 5 байтов, например. char bytes[5] = "lalla"
. Если размер массива не менее 6 или не задан, будет завершающий нулевой байт.
Это может помочь, если вы конкретно упоминается, что проблема вы спрашиваете о том, - код, который вы размещены, по меньшей мере три отдельных проблемы, но в вопросе никогда не упоминается ни одно из них. –