c - не может решить Неверное чтение размера 1 на клиент-серверной программе - PullRequest
0 голосов
/ 05 февраля 2019

клиент и сервер обмениваются сообщениями, отправляя структуры такого типа:

typedef struct {
    op_t     op;   
    char sender[MAX_NAME_LENGTH+1];
} message_hdr_t;

typedef struct {
    char receiver[MAX_NAME_LENGTH+1];
    unsigned int   len;  
} message_data_hdr_t;

typedef struct {
    message_data_hdr_t  hdr;
    char               *buf;
} message_data_t;

typedef struct {
    message_hdr_t  hdr;
    message_data_t data;
} message_t;

сообщения, которыми обмениваются клиент и сервер, поступают корректно, и выполнение продолжается, но valgrind возвращает ошибку:

==4179== Invalid read of size 1
==4179==    at 0x4C32D04: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4179==    by 0x50B84D2: vfprintf (vfprintf.c:1643)
==4179==    by 0x50BFF25: printf (printf.c:33)
==4179==    by 0x10A122: threadF (main.c:151)
==4179==    by 0x4E436DA: start_thread (pthread_create.c:463)
==4179==    by 0x517C88E: clone (clone.S:95)
==4179==  Address 0x5452134 is 0 bytes after a block of size 4 alloc'd
==4179==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4179==    by 0x109B2B: readData (connections.h:103)
==4179==    by 0x109C17: readMsg (connections.h:134)
==4179==    by 0x10A0B0: threadF (main.c:146)
==4179==    by 0x4E436DA: start_thread (pthread_create.c:463)
==4179==    by 0x517C88E: clone (clone.S:95)

вот как я заполняю структуру на сервере в readData ();Вы можете считать readn прочитанным.

#define SYSCALL(r,c,msg) \
    if((r=c)==-1) {perror(msg);

//other reads and writes
msg->data.buf=malloc(msg->data.hdr.len*sizeof(char));
SYSCALL(notused,readn(fd,msg->data.buf,msg->data.hdr.len*sizeof(char)),"read_data_buf");            
if(notused==0){
    return -1;
}

, и я получаю сообщение об ошибке, когда я выполняю printf на main.c: 151

printf("BODY: %s\n",msg->data.buf);

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Согласно этому сообщению

==4179==  Address 0x5452134 is 0 bytes after a block of size 4 alloc'd

вы выделили 4 байта.

Ваш printf вызов

printf("BODY: %s\n",msg->data.buf);

ожидает найти строку, оканчивающуюся на \0

Возможно, байты, которые вы читаете с SYSCALL(notused,readn(..., не содержат '\0' в этих 4 байтах, поэтому strlen читает следующий байт после окончания выделенной памяти.

Один из вариантов решения этой проблемы - выделить еще один байт и добавить '\0' к полученным данным.

0 голосов
/ 05 февраля 2019

вероятно

msg->data.buf=malloc(msg->data.hdr.len*sizeof(char));
SYSCALL(notused,readn(fd,msg->data.buf,msg->data.hdr.len*sizeof(char)),"read_data_buf");            

должно быть

msg->data.buf=malloc(msg->data.hdr.len + 1);
SYSCALL(notused,readn(fd,msg->data.buf,msg->data.hdr.len),"read_data_buf");            
msg->data.buf[msg->data.hdr.len] = 0;

, чтобы добавить место для завершающего нулевого символа и установить его

Однако выуверен msg->data.buf это строка для печати?Как вы кодируете свои структуры во время обмена?


Опять sizeof(char) равен 1 по определению, умножать на него бесполезно

...