C语言中遇到的一个栈和堆的问题

C中一个异常挂死,捣腾了大半天。先记录下来。因为是公司代码帖出来不太适合。精简之。主要讲述问题。

 

好了现在讲述问题,主要遇到的问题是C 语言中,char p[] 这种不定长数组的应用。

typedef struct

{

int8_ file_path[64];

}file_path_t;

 

 

typedef struct

{

uint8_ delete_all;  

file_path_t file[]; // =========================>如这里,设计思想是可以传N个长度的file_path_t类型数组。这个file[]根据实际需要来决定。

}file_delete_req_t;

 

而在实际应用中,我们如果理解错误会遇到跟我一样的问题。如下:

void send_net_pack_file_delete_req(int socketfd)

{

unsigned char cmd[1024];

int i = 0;

msg_head_t Msghead;    //注意变量是在栈上

file_delete_req_t file_delete_req; //注意变量是在栈上

    

 

    memset(&Msghead, 0, sizeof(msg_head_t));

memset(&file_delete_req, 0, sizeof(file_delete_req_t));

 

file_delete_req.delete_all = 1;

strncpy(file_delete_req.file[0].file_path, "d:\\show\\log", sizeof("d:\\show\\log"));

 

 

net_pack_file_delete_req(Msghead, file_delete_req);

 

return;

}

 

红色部分,表面上看起来是没有问题。

msg_head_t Msghead;    

file_delete_req_t file_delete_req;

一个结构体类型的变量我们随处可以。

 

我先把完整代码帖出来。

///begin/

#include <stdio.h>

 

 

typedef signed char int8_;

typedef signed short int int16_;

typedef signed int int32_; //signed long

typedef signed long long int64_;

typedef unsigned char uint8_;

typedef unsigned short int uint16_;

typedef unsigned int uint32_; //unsigned long

typedef unsigned long long uint64_;

 

 

#define MSG_HEAD_MAGIC "begin"

 

 

typedef struct

{

int8_ file_path[64];

}file_path_t;

 

 

typedef struct

{

uint8_ delete_all;  

file_path_t file[];

}file_delete_req_t;

 

 

typedef struct

{

int8_   magic[4];

uint8_  msg_type;

uint8_  cmd_class;

uint16_ cmd_id;

uint32_ data_len;

uint32_ version;

int8_   reserved[4];   

}msg_head_t;

 

 

static int net_set_head(file_delete_req_t *req, msg_head_t *head, uint8_ msg_type, uint8_ cmd_class,

uint16_ cmd_id, uint32_ data_len)

{

int i = 0;

 

if(!head)

return -1;

    file_path_t *file = (file_path_t *)((char*)req + sizeof(char));

 

    printf("head->magic %s\n", head->magic);

printf("head->magic %x\n", head->msg_type);

printf("head->magic %x\n", head->cmd_class);

printf("head->magic %x\n", head->cmd_id);

printf("head->magic %x\n", head->data_len);

printf("head->magic %x\n", head->version);

 

 

memcpy((void*)head->magic, (const void*)MSG_HEAD_MAGIC, strlen(MSG_HEAD_MAGIC));

printf("head->magic %s\n", head->magic);

printf("%s, L:%d\n", file->file_path, __LINE__);

head->msg_type = msg_type;

printf("%s, L:%d\n", file->file_path, __LINE__);

head->cmd_class = cmd_class;

printf("%s, L:%d\n", file->file_path, __LINE__);

head->cmd_id = cmd_id;

printf("%s, L:%d\n", file->file_path, __LINE__);

head->data_len = data_len;

printf("%s, L:%d\n", file->file_path, __LINE__);

head->version = 0x010203;

printf("%s, L:%d\n", file->file_path, __LINE__);

 

    printf("head->magic %s\n", head->magic);

printf("head->magic %x\n", head->msg_type);

printf("head->magic %x\n", head->cmd_class);

printf("head->magic %x\n", head->cmd_id);

printf("head->magic %x\n", head->data_len);

printf("head->magic %x\n", head->version);

 

return 0;

}

 

 

 

int net_pack_file_delete_req(msg_head_t *head, file_delete_req_t *req)

{

int i = 0;

int data_len = sizeof(req->file[0].file_path);

 

printf("data_len:%d req%x, head:%x\n", data_len, req, head);

    net_set_head(req, head, 1, 2, 3, data_len);

return 0;

}

 

 

void send_net_pack_file_delete_req(int socketfd)

{

unsigned char cmd[1024];

int i = 0;

msg_head_t Msghead;

file_delete_req_t file_delete_req;

    

 

    memset(&Msghead, 0, sizeof(msg_head_t));

memset(&file_delete_req, 0, sizeof(file_delete_req_t));

 

file_delete_req.delete_all = 1;

strncpy(file_delete_req.file[0].file_path, "d:\\show\\log", sizeof("d:\\show\\log"));

 

 

net_pack_file_delete_req(&Msghead, &file_delete_req);

 

return;

}

 

int main(void)

{

  

send_net_pack_file_delete_req(111);

 

return 0;

}

 

 

///end///

运行结果:

 

有心人会发现,Msghead变量成功的将file_delete_req的内容给改变了。虽然我们在调用net_set_head()函数时,只是希望给Msghead变量填值。但确发现file_delete_req变量的内容也被改变了。归其原因还是栈的问题。

 

比喻我们做实验,改造一下send_net_pack_file_delete_req()函数。往file_delete_reqMsghead之间插入一个大的空间。一切数据又都正常。想不明白为什么会被采。

file_delete_req_t file_delete_req;

unsigned char cmd[1024];

msg_head_t Msghead;

 

void send_net_pack_file_delete_req(int socketfd)

{

int i = 0;

file_delete_req_t file_delete_req;

unsigned char cmd[1024];

msg_head_t Msghead;

    memset(&Msghead, 0, sizeof(msg_head_t));

memset(&file_delete_req, 0, sizeof(file_delete_req_t));

 

file_delete_req.delete_all = 1;

strncpy(file_delete_req.file[0].file_path, "d:\\show\\log", sizeof("d:\\show\\log"));

 

 

net_pack_file_delete_req(&Msghead, &file_delete_req);

 

return;

}

 

解决办法就是用malloc申请一个“”给file_delete_req_t file_delete_req; msg_head_t Msghead;使用。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值