OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4028|回复: 7

stm32f1链表仿真出现问题cannot access memory

[复制链接]

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2019-6-28
在线时间
22 小时
发表于 2021-1-19 11:03:18 | 显示全部楼层 |阅读模式
5金钱
向各位大佬求教个问题:
1、我的程序用串口接收PC端的数据,发现接收到第四个时就无法在接收;仿真发现进入了HardFault_Handle()函数中;
0.JPG
2、command里面显示:
1.JPG
3、我的代码中是将接收到的串口数据保存到一个队列中,用到了动态内存分配:
结构体定义:
typedef union
{
        float fv;
        uint8_t cv[4];
}float_union;

typedef struct
{
        unsigned char start_code1;       //起始码1
        unsigned char start_code2;       //起始码2
        unsigned char func_code;         //功能码
        unsigned char sending_num;      
        unsigned char this_sending_num;
        float_union joint_pos[6];        
        float_union joint_vel[6];      
        float_union joint_acc[6];      
        float_union joint_t;            
        unsigned char crc_code;         
}RosDataNodeStruct;              

typedef struct RosData
{
        RosDataNodeStruct data;
        struct RosData *next;
}RosDataNode;


初始化:

RosDataNode* RosQueueInit()
{
        RosDataNode* queue = (RosDataNode*)malloc(sizeof(RosDataNode));
        queue->data = RosDataQueueNodeInit;
        queue->next = NULL;
        return queue;
}
/*数据入队列,返回队列新的尾指针*/
RosDataNode* RosDataEnterQueue(RosDataNode* rear,RosDataNodeStruct rosdata)
{
        RosDataNode* enElem = (RosDataNode*)malloc(sizeof(RosDataNode));   //分配节点空间(动态内存分配)
        enElem->data        = rosdata;      //节点数据保存
        enElem->next        = NULL;         //节点指针指向NULL
        rear->next          = enElem;       //新节点放到rear节点后
        rear                = enElem;       //得到新的队尾
        return rear;                    //返回新的队尾指针
}
/*数据出队列,返回队列新的头指针*/

RosDataNodeStruct RosDataOutQueue(RosDataNode* top,RosDataNode* rear)
{
        RosDataNodeStruct temp = {0};
        RosDataNode *p         = {0};
        if(top->next == NULL)   //队列为空
        {
                printf("queue is empty"); //????????????
                return temp;
        }
        p = top->next;
        temp = p->data;
        top->next = p->next;   //头指针指向下一个节点
        if(rear == p)          //出队后只剩一个节点则rear=top
        {
                ros_rear = top;
        }
        free(p);              //释放节点内存
        return temp;
}


ros_queue=ros_top=ros_rear=RosQueueInit();  
初始化后仿真发现rear->next有很多
2.JPG


问题:1、仿真出现的问题是越界了吗?2、为什么初始化后会有如此多的rear->next,不是应该只有一个空指针吗?会不会是这种情况导致的内存不够?谢谢!

最佳答案

查看完整内容[请看2#楼]

你应该是来一个数据,建立一个节点,如果链头为空,建立链头,如果有链头了,新的节点加入链尾。链头一定是最先来的,然后在主循环里面判断,如果链头不是空,马上处理链头数据,然后free,返回新的链头,下一个循环再如此判断。只要链头不丢,就一定可以处理完数据。 //新的信息加入链尾,如果没有头,就建立头,如果只有头,头也是尾,如果有头了,新的信息就是尾,尾的next一定为NULL,只要抓住链头,链表就不会丢 Stc_UserRx ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1817
金钱
1817
注册时间
2014-6-27
在线时间
975 小时
发表于 2021-1-19 11:03:19 | 显示全部楼层
你应该是来一个数据,建立一个节点,如果链头为空,建立链头,如果有链头了,新的节点加入链尾。链头一定是最先来的,然后在主循环里面判断,如果链头不是空,马上处理链头数据,然后free,返回新的链头,下一个循环再如此判断。只要链头不丢,就一定可以处理完数据。
//新的信息加入链尾,如果没有头,就建立头,如果只有头,头也是尾,如果有头了,新的信息就是尾,尾的next一定为NULL,只要抓住链头,链表就不会丢
Stc_UserRx_t* Creat_Rf_Rx_One_Node(u64 dat)//新的信息加入链尾
{
     Stc_UserRx_t *p_new=NULL;
           u64 *p_64=NULL;
     p_new=(Stc_UserRx_t*)malloc(sizeof(Stc_UserRx_t));
     if(p_new==NULL)return p_new;
           p_64=(u64*)p_new;
           *p_64=dat;
//     p_new->devAdr=dat>>4;       
//     p_new->devDat=dat;
     p_new->devTyp=dat>>22;       
     if(Rf_Rx_Head==NULL)
                 Rf_Rx_Head=p_new;
         else
                 Rf_Rx_Tail->next=p_new;

         Rf_Rx_Tail=p_new;
         Rf_Rx_Tail->next=NULL;       
     return p_new;
}

//主循环
while(1)
{
       if(Rf_Rx_Head)
{
    //处理数据
    //保存头的指针,头的下一个做为头,如果到尾了,头就是尾,尾的下一个就是NULL。
   //释放头
}

}
回复

使用道具 举报

2

主题

458

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4462
金钱
4462
注册时间
2018-5-14
在线时间
956 小时
发表于 2021-1-19 11:23:32 | 显示全部楼层
那么多的next是对的啊,你没看next指向的是0x00000000吗,代表next是个空指针。hardfault大概率是你代码没有判断next是不是空指针就调用导致的非法访问
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2019-6-28
在线时间
22 小时
 楼主| 发表于 2021-1-19 11:28:34 | 显示全部楼层
姚先起 发表于 2021-1-19 11:23
那么多的next是对的啊,你没看next指向的是0x00000000吗,代表next是个空指针。hardfault大概率是你代码没 ...

你的意思是我每次存入队列需要先判断rear->next是否为NULL吗?
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2019-6-28
在线时间
22 小时
 楼主| 发表于 2021-1-19 12:26:14 | 显示全部楼层
发现在接到第四个点的时候就无法为新节点分配内存,这是什么原因,感觉内存不该这么小啊
回复

使用道具 举报

3

主题

808

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3874
金钱
3874
注册时间
2017-3-7
在线时间
1690 小时
发表于 2021-1-19 14:01:24 | 显示全部楼层
RosDataEnterQueue函数就有问题,应该传指针的指针,要不然你的rear没有改变,其实
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2019-6-28
在线时间
22 小时
 楼主| 发表于 2021-1-19 19:33:34 | 显示全部楼层
a5820736 发表于 2021-1-19 14:01
RosDataEnterQueue函数就有问题,应该传指针的指针,要不然你的rear没有改变,其实

发现是堆栈溢出了,这个函数毛事没有问题
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2019-6-28
在线时间
22 小时
 楼主| 发表于 2021-1-20 09:05:40 | 显示全部楼层
TinyBoy 发表于 2021-1-19 19:33
你应该是来一个数据,建立一个节点,如果链头为空,建立链头,如果有链头了,新的节点加入链尾。链头一定是 ...

是的,发现了是堆栈溢出问题,目前已经解决了,看后续还会不会有bug了,谢谢解答
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-15 18:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表