Ошибка сегментации в функции сериализации - PullRequest
1 голос
/ 11 июня 2019

Проблема в переменной MSG. Каждое сообщение может иметь размер, который может изменяться, поэтому переменная payload_len. Я не могу определить ошибку в коде. Все мои попытки привели к «ошибке сегментации».

PKG

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);
}

Ответы [ 2 ]

1 голос
/ 11 июня 2019

Вы копируете указатель msg, а не данные, на которые он указывает.Но вы используете длину полезной нагрузки, поэтому вы получаете доступ за пределами struct, если 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);
0 голосов
/ 11 июня 2019

Я вижу две проблемы в вашем коде, которые выглядят подозрительно:

Во-первых, в вашей функции сериализации вы передаете адрес указателя (не значение указателя) в 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));

Write

pkgs->msg = malloc(pkgs->payload_len);
memcpy(&pkgs->msg[0], &data[12], pkgs->payload_len);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...