memcpy на 32 и 64 битных машинах [решено]

Модератор: Fastman

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

memcpy на 32 и 64 битных машинах [решено]

Непрочитанное сообщение helloworld » 2009-10-08 6:32:36

Немогу понять почему в 32-битном линуксе memcpy ведет себя странно. В 64 - все окей.

Вратце - есть массив char out[4096]; который в хексе выглядит так:

Код: Выделить всё

        for (i=0;i<bytelen;i++)
        {
                printf("%02x", out[i]);
        }

        printf("\n");

Код: Выделить всё

066e657473656309636f6c6f73746174650365647500
Code:

Код: Выделить всё

struct HDR_Message
{
        u_int16_t ID;
        u_int16_t VALUES;
        u_int16_t QDCOUNT;
        u_int16_t ANCOUNT;
        u_int16_t NSCOUNT;
        u_int16_t ARCOUNT;
} __attribute__((__packed__));
typedef struct HDR_Message header;

struct Question_Message
{
        u_char   *QNAME;
        u_int16_t QTYPE;
        u_int16_t QCLASS;

} __attribute__((__packed__));
typedef struct Question_Message question;

........................

        // creating new header for DNS question
        header *headerPtr = malloc(sizeof(header));
        if (headerPtr == NULL)
        {
                fprintf(stderr, "Failed to allocate memory for header\n");
                exit(1);
        }
        headerPtr->ID = htons(50);
        headerPtr->VALUES = 0;
        headerPtr->QDCOUNT = htons(1);
        headerPtr->ANCOUNT = 0;
        headerPtr->NSCOUNT = 0;
        headerPtr->ARCOUNT = 0;

       question *questionPtr = malloc(sizeof(question));
        if (questionPtr == NULL)
        {
                fprintf(stderr, "Failed to allocate memory for question");
                exit(1);
        }

        questionPtr->QNAME = malloc(sizeof(bytelen));
        if (questionPtr->QNAME == NULL)
        {
                fprintf(stderr, "Failed to allocate memory for QNAME");
                exit(1);
        }
        memcpy(questionPtr->QNAME, out, bytelen);
        questionPtr->QTYPE = htons(48);
        questionPtr->QCLASS = htons(1);

        // calculate total number of bytes to send via socket
        int bufsize = sizeof(header)+bytelen+sizeof(questionPtr->QTYPE)+sizeof(questionPtr->QCLASS);
        printf("sizeof bufsize is %d\n", bufsize);


        buf = malloc(bufsize);

        // copy header structure
        memcpy(buf, headerPtr, sizeof(header));


        // copy byte order of domain
[b]        memcpy(buf+sizeof(header), questionPtr->QNAME, bytelen);
        //memcpy(buf+sizeof(header), out, bytelen);[/b]

       memcpy(buf+sizeof(header)+bytelen, &questionPtr->QTYPE, sizeof(questionPtr->QTYPE));
        memcpy(buf+sizeof(header)+bytelen+sizeof(questionPtr->QTYPE), &questionPtr->QCLASS, sizeof(questionPtr->QCLASS));



        // debuggin
        for (i=0;i<bufsize;i++)
        {
                printf("%02x", buf[i]);
        }
        printf("\n");

всс

Ответ:

Код: Выделить всё

out:
066e657473656309636f6c6f73746174650365647500
Printing qname ...
066e657473656309636f6c6f73746174650365647500

sizeof bufsize is 38
003200000001000000000000066e657473656309636f6c6f3100000000320000000100300001
а должно быть так, но это получается только если
// memcpy(buf+sizeof(header), questionPtr->QNAME, bytelen);
memcpy(buf+sizeof(header), out, bytelen);

Код: Выделить всё

003200000001000000000000066e657473656309636f6c6f7374617465036564750000300001
вопрос, куда девается "вторая часть" если копировать из указателя а не из массива?
Последний раз редактировалось helloworld 2009-10-08 6:37:32, всего редактировалось 1 раз.

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
helloworld
ст. сержант
Сообщения: 368
Зарегистрирован: 2007-10-03 8:06:37
Откуда: Northern Colorado

Re: memcpy на 32 и 64 битных машинах

Непрочитанное сообщение helloworld » 2009-10-08 6:35:30

Прошу прощения, моя ошибка в коде

Код: Выделить всё

        questionPtr->QNAME = malloc(sizeof(bytelen));
на

Код: Выделить всё

        questionPtr->QNAME = malloc(bytelen);
Пишу sizeof уже на автомате если передним malloc : ))))

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: memcpy на 32 и 64 битных машинах [решено]

Непрочитанное сообщение paradox » 2009-10-09 20:18:39

главное что бы sizeof ом ты размер строки не начал мерять))) ато есть такие уникумы