LINUX.ORG.RU

не понятно: memcpy


0

0

char *in_buf;
struct my_struct lala1;

in_buf = (char *) mmap(0, stat_buf.st_size, PROT_READ, MAP_PRIVATE, fdd, 0);

memcpy((struct my_struct *) &lala1, (char *) in_buf, sizeof(struct my_struct));
После этого:
В gcc 4.1.2 - Все нормально.
В gcc 4.2.4 - Segmentation fault.

С чем это может быть связано ???

P.S. структура my_struct - 4 поля типа uint32_t.


> memcpy((struct my_struct *) &lala1, (char *) in_buf, sizeof(struct my_struct));

man memcpy:

void *memcpy(void *dest, const void *src, size_t n);

почему у тебя странные адреса передаются, не (void *) ?

Spectr ★★★
()

> in_buf = (char *) mmap(0, stat_buf.st_size, PROT_READ, MAP_PRIVATE, fdd, 0);

Что такое stat_buf.st_size и какое в нём значение?

> memcpy((struct my_struct *) &lala1, (char *) in_buf, sizeof(struct my_struct));


Про странное и бессмысленное приведение типов указателей уже сказали, но это не должно быть связано с ошибкой.

Deleted
()
Ответ на: комментарий от Spectr

> почему у тебя странные адреса передаются, не (void *) ?

Что-то не понял...
По-твоему такая запись тоже странная ?

s = (char *) malloc(size);

man malloc

drZlo
() автор топика
Ответ на: комментарий от Deleted

Ну и в догонку самое вкусное: _НИКОГДА_ не пытайся читать/писать в файлы/потоки/другие_внешние_для_программы_вещи обычные структуры, так как поля в них выравниваются (по разному на разных архитектурах, с разными опциями компиляции и т.п.) и данные могут располагаться в памяти совсем не так, как ты ожидаешь. Google << "Fighting the Lemmings".

Deleted
()
Ответ на: комментарий от Deleted

> Что такое stat_buf.st_size и какое в нём значение?

stat(file_name, &stat_buf);
В нем размер файла file_name, правильный.

drZlo
() автор топика

Кстати, если указатель вернется MAP_FAILED - попробуй использовать MAP_SHARED вместо MAP_PRIVATE.

Spectr ★★★
()
Ответ на: комментарий от drZlo

> Что-то не понял...

Там преобразование указателей просто бессмысленное, так как компилятор всё равно автоматически преобразует их до (void *) и (const void *). Да и вообще, ИМХО лучше не указывать явно преобразования, которые по стандарту должны происходить автоматически. А то когда-нибудь ты ошибёшься (передашь совсем левый указатель в функцию), а компилятор не выдаст важный варнинг, так как подумает что ты знаешь что делаешь раз указал явное преобразование.

Deleted
()
Ответ на: комментарий от drZlo

> stat(file_name, &stat_buf);
> В нем размер файла file_name, правильный.


Минимизируй количество кода на котором воспроизводится баг. И если сам в процессе не разберёшься - выкладывай. Но только весь исходник, иначе будет не понятно.

Deleted
()
Ответ на: комментарий от Deleted

а-а-а-а! позор мне, спешил, не проверил open. Какие-то косяки с
кодировкой, вместо имени файла - кракозябры, хотя размер прально
определился, странно.
Все, победил, Всем спасибо!

А на счет твоего поста выше по поводу не приведения к своим типаи
файлов и т.д. - я структуры специально выравниваю (сейчас 4 uint'a)
и такая запись нормально: p_lala = (my_struct *) in_buf, что тут
может быть ? Вот, если бы
struct a {
uint32_t u1;
char c;
uint32_t u2;
};
Тогда - да...

drZlo
() автор топика
Ответ на: комментарий от drZlo

> я структуры специально выравниваю (сейчас 4 uint'a)

How?

Deleted
()
Ответ на: комментарий от drZlo

> я структуры специально выравниваю (сейчас 4 uint'a)

А ты точно уверен, что компилятор не захочет вдруг выравнивать uint32_t по 8 байт?

const86 ★★★★★
()
Ответ на: комментарий от const86

> А ты точно уверен, что компилятор не захочет вдруг выравнивать uint32_t по 8 байт?

Ога ога. Конечно можно добавить __attribute__((__packed__)), но это 1) гыцыцызм, 2) приведёт к неработоспособности на процессорах, которые не умеют работать с невыровненными данными и 3) не избавит от проблемы с порядком байт (которая тоже имеет место быть).

Deleted
()
Ответ на: комментарий от Deleted

> 2) приведёт к неработоспособности на процессорах, которые не умеют работать с невыровненными данными

А зачем такая структура нужна, если в неё смотреть опасно? Наверное, всё-таки компилятор будет генерить жутко неэффективный код, который выковырнет плохо выровненный атрибут из структуры.

const86 ★★★★★
()
Ответ на: комментарий от const86

> А зачем такая структура нужна, если в неё смотреть опасно?

Из неё можно вытаскивать данные тем же memcpy'ем.

> Наверное, всё-таки компилятор будет генерить жутко неэффективный код, который выковырнет плохо выровненный атрибут из структуры.


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

Deleted
()
Ответ на: комментарий от drZlo

> Что-то не понял...

> По-твоему такая запись тоже странная ?

> s = (char *) malloc(size);

> man malloc

Да, странная.

man malloc

надо писать:

s = malloc(size);

trapezoid
()
Ответ на: комментарий от Deleted

>> Наверное, всё-таки компилятор будет генерить жутко неэффективный код, который выковырнет плохо выровненный атрибут из структуры.

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

Оно может и SIGBUS'ом закончиться…

trapezoid
()
Ответ на: комментарий от drZlo

>я структуры специально выравниваю

а про big endian что-нибудь слышал? :)

xydo ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.