序列化功能中的分段错误

时间:2019-06-10 21:22:48

标签: c serialization

问题出在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 个答案:

答案 0 :(得分:1)

您正在复制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);

答案 1 :(得分:0)

我在您的代码中发现了两个可疑的问题:

首先,在序列化函数中,将指针的地址(而不是指针值)传递到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传递给{{1} }-功能。而不是

construct

int x = pkgs->payload_len;
char msg[x];
memcpy(&pkgs->msg[0], &data[12], sizeof(msg));