Проблема в переменной MSG. Каждое сообщение может иметь размер, который может меняться, поэтому переменная payload_len. Не могу определить ошибку в коде. Все мои попытки привели к "ошибке сегментации".
ПКГ
typedef struct pkg{
uint32_t payload_len;
uint32_t psecret;
uint16_t step;
uint16_t student_num;
char* msg;
}Pkg;
построить функцию
Pkg* constructPKG(int payload_len, int psecret, short step, char* msg){
Pkg* pkgS = (Pkg*) malloc(sizeof(Pkg));
pkgS->payload_len = payload_len;
pkgS->psecret = psecret;
pkgS->step = step;
pkgS->student_num = STUDENT_NUM;
pkgS->msg=msg;
return pkgS;
}
Функция сериализации
void serialize(Pkg* pkgS, char *data){
uint32_t temp_32;
uint16_t temp_16;
temp_32 = htonl(pkgS->payload_len);
memcpy(&data[0], &temp_32, sizeof(temp_32));
temp_32 = htonl(pkgS->psecret);
memcpy(&data[4], &temp_32, sizeof(temp_32));
temp_16 = htons(pkgS->step);
memcpy(&data[8], &temp_16, sizeof(temp_16));
temp_16 = htons(pkgS->student_num);
memcpy(&data[10], &temp_16, sizeof(temp_16));
int x = pkgS->payload_len;
char msg[x];
memcpy(&data[12], &pkgS->msg,sizeof(msg));
}
Десериализовать функцию
void deserialize(char *data, Pkg* pkgs){
uint32_t temp_32;
uint16_t temp_16;
memcpy(&temp_32, &data[0], sizeof(temp_32));
pkgs->payload_len=ntohl(temp_32);
memcpy(&temp_32, &data[4], sizeof(temp_32));
pkgs->psecret=ntohl(temp_32);
memcpy(&temp_16, &data[8], sizeof(temp_16));
pkgs->step=ntohs(temp_16);
memcpy(&temp_16, &data[10], sizeof(temp_16));
pkgs->student_num=ntohs(temp_16);
int x = pkgs->payload_len;
char msg[x];
memcpy(&pkgs->msg[0], &data[12], sizeof(msg));
}
Функция печати
void printPkg(Pkg* pkgS){
printf("Payload_len: %d\n",pkgS->payload_len);
printf("Psecret: %d\n",pkgS->psecret);
printf("Step: %d\n",pkgS->step);
printf("Student_num: %d\n",pkgS->student_num);
printf("MSG: %s\n",pkgS->msg);
}
` char *hello = "Привет, мир"; символ *данные; Pkg *x = конструкцияPKG(strlen(привет), 12, 2, привет); Пакет *y = конструкцияPKG(0, 0, 0, NULL);`
@JefersonJuliani Добавляйте в вопрос код, а не комментарии.
Вам не нужна переменная msg
. sizeof(msg)
то же, что x
.
Вы копируете указатель msg
, а не данные, на которые он указывает. Но вы используете длину полезной нагрузки, поэтому вы получаете доступ за пределы struct
if payload_len > sizeof(char*)
.
Изменять
int x = pkgS->payload_len;
char msg[x];
memcpy(&data[12], &pkgS->msg,sizeof(msg));
к
char msg[x];
memcpy(&data[12], pkgS->msg, pgkS->payload_len);
А в функции deserialize()
вам нужно выделить место для msg
перед копированием в нее. Изменять:
int x = pkgs->payload_len;
char msg[x];
memcpy(&pkgs->msg[0], &data[12], sizeof(msg));
к
pkgs->msg = malloc(pkgs->payload_len);
memcpy(pkgs->msg, &data[12], pkgs->payload_len);
Я вижу две проблемы в вашем коде, которые выглядят подозрительно:
Во-первых, в вашей функции сериализации вы передаете адрес указателя (а не значение указателя) в memcpy
. Это приведет к неопределенному поведению (чтение из памяти, которая не принадлежит допустимому объекту). Изменить
int x = pkgS->payload_len;
char msg[x];
memcpy(&data[12], &pkgS->msg,sizeof(msg));
к ...
memcpy(&data[12], pkgS->msg, pkgS->payload_len);
Во-вторых, при десериализации вы копируете в pkgs->msg
, но, похоже, у вас не было зарезервировано памяти для него (в комментарии вы пишете, что передаете NULL
в construct
-функцию. Вместо
int x = pkgs->payload_len;
char msg[x];
memcpy(&pkgs->msg[0], &data[12], sizeof(msg));
Напишите
pkgs->msg = malloc(pkgs->payload_len);
memcpy(&pkgs->msg[0], &data[12], pkgs->payload_len);
пожалуйста, покажите код, где вы резервируете память для
pkgS->msg
перед вызовом десериализации (или сериализации); параметрconstruction
просто убийцmsg
...