VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 451|回复: 6

[求助] 缓冲区总是崩溃

[复制链接]
16_avatar_middle
在线会员 突突突突 发表于 2018-7-24 16:16:33 | 显示全部楼层 |阅读模式
3驿站币
有一个环形缓冲区,一个读的一个写的,先写然后再读,分别在两个线程中,现在的问题是在写入3次的时候会崩溃下面是代码
  1. int CCycleBuffer::write(char* buf, int count)
  2. {
  3.         if (count <= 0)
  4.                 return 0;
  5.         m_bEmpty = false;
  6.         // 缓冲区已满,不能继续写入
  7.         if (m_bFull)
  8.         {
  9.                 return 0;
  10.         }
  11.         else if (m_nReadPos == m_nWritePos)// 缓冲区为空时
  12.         {
  13.                 /*                          == 内存模型 ==
  14.                 (empty)             m_nReadPos                (empty)
  15.                 |----------------------------------|-----------------------------------------|
  16.                 m_nWritePos        m_nBufSize
  17.                 */
  18.                 int leftcount = m_nBufSize - m_nWritePos;
  19.                 if (leftcount > count)
  20.                 {
  21.                         memcpy(m_pBuf + m_nWritePos, buf, count);
  22.                         m_nWritePos += count;
  23.                         m_bFull = (m_nWritePos == m_nReadPos);
  24.                         return count;
  25.                 }
  26.                 else
  27.                 {
  28.                         memcpy(m_pBuf + m_nWritePos, buf, leftcount);
  29.                         m_nWritePos = (m_nReadPos > count - leftcount) ? count - leftcount : m_nWritePos;
  30.                         memcpy(m_pBuf, buf + leftcount, m_nWritePos);
  31.                         m_bFull = (m_nWritePos == m_nReadPos);
  32.                         return leftcount + m_nWritePos;
  33.                 }
  34.         }
  35.         else if (m_nReadPos < m_nWritePos)// 有剩余空间可写入
  36.         {
  37.                 /*                           == 内存模型 ==
  38.                 (empty)                 (data)                     (empty)
  39.                 |-------------------|----------------------------|---------------------------|
  40.                 m_nReadPos                m_nWritePos       (leftcount)
  41.                 */
  42.                 // 剩余缓冲区大小(从写入位置到缓冲区尾)

  43.                 int leftcount = m_nBufSize - m_nWritePos;
  44.                 int test = m_nWritePos;
  45.                 if (leftcount > count)   // 有足够的剩余空间存放
  46.                 {
  47.                         memcpy(m_pBuf + m_nWritePos, buf, count);//有的时候在这里,明明空间 是够的为什么会崩溃呢。
  48.                         m_nWritePos += count;
  49.                         m_bFull = (m_nReadPos == m_nWritePos);
  50.                         assert(m_nReadPos <= m_nBufSize);有的时候在这里这里也是条件也是满足的也会崩溃
  51.                         assert(m_nWritePos <= m_nBufSize);
  52.                         return count;
  53.                 }
  54.                 else       // 剩余空间不足
  55.                 {
  56.                         // 先填充满剩余空间,再回头找空间存放
  57.                         memcpy(m_pBuf + test, buf, leftcount);
  58.                         m_nWritePos = (m_nReadPos >= count - leftcount) ? count - leftcount : m_nReadPos;
  59.                         memcpy(m_pBuf, buf + leftcount, m_nWritePos);
  60.                         m_bFull = (m_nReadPos == m_nWritePos);
  61.                         assert(m_nReadPos <= m_nBufSize);
  62.                         assert(m_nWritePos <= m_nBufSize);
  63.                         return leftcount + m_nWritePos;
  64.                 }
  65.         }
  66.         else
  67.         {
  68.                 /*                          == 内存模型 ==
  69.                 (unread)                 (read)                     (unread)
  70.                 |-------------------|----------------------------|---------------------------|
  71.                 m_nWritePos    (leftcount)    m_nReadPos
  72.                 */
  73.                 int leftcount = m_nReadPos - m_nWritePos;
  74.                 if (leftcount > count)
  75.                 {
  76.                         // 有足够的剩余空间存放
  77.                         memcpy(m_pBuf + m_nWritePos, buf, count);
  78.                         m_nWritePos += count;
  79.                         m_bFull = (m_nReadPos == m_nWritePos);
  80.                         assert(m_nReadPos <= m_nBufSize);
  81.                         assert(m_nWritePos <= m_nBufSize);
  82.                         return count;
  83.                 }
  84.                 else
  85.                 {
  86.                         // 剩余空间不足时要丢弃后面的数据
  87.                         memcpy(m_pBuf + m_nWritePos, buf, leftcount);
  88.                         m_nWritePos += leftcount;
  89.                         m_bFull = (m_nReadPos == m_nWritePos);
  90.                         assert(m_bFull);
  91.                         assert(m_nReadPos <= m_nBufSize);
  92.                         assert(m_nWritePos <= m_nBufSize);
  93.                         return leftcount;
  94.                 }
  95.         }
  96. }
复制代码





上一篇:MFC 打造聊天程序时遇到的窗口伸缩问题
下一篇:Windows x86和x64问题

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

55_avatar_middle
在线会员 anzun 发表于 2018-7-24 18:03:47 | 显示全部楼层
感觉是多线程同步的问题,一个写,一个在读。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

51_avatar_middle
online_admins Syc 发表于 2018-7-24 18:09:27 | 显示全部楼层
调试下看看这句 memcpy(m_pBuf + m_nWritePos, buf, count); 在内存拷贝的时候是不是目标地址为空,或者拷贝的数据长度超过目标缓冲区了?
具体调试调试看看,容易发现问题

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

16_avatar_middle
ico_lz  楼主| 突突突突 发表于 2018-7-25 09:37:02 | 显示全部楼层
anzun 发表于 2018-7-24 18:03
感觉是多线程同步的问题,一个写,一个在读。

是2个线程用,一个读的一个写的,但是这个是环形缓冲区,一个读的一个写的应该不会出问题

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

16_avatar_middle
ico_lz  楼主| 突突突突 发表于 2018-7-25 09:54:22 | 显示全部楼层
Syc 发表于 2018-7-24 18:09
调试下看看这句 memcpy(m_pBuf + m_nWritePos, buf, count); 在内存拷贝的时候是不是目标地址为空,或者拷 ...

但是如果进入到这里的话说明剩余空间是够的,为什么还会超过目标缓冲区了呢,刚才调试了一下memcpy(m_pBuf + m_nWritePos, buf, count); count=192000的时候崩溃了,而写指针的位置也不过3840个这个大小是完全够的4 120 576这个是分配的大小。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

16_avatar_middle
ico_lz  楼主| 突突突突 发表于 2018-7-25 10:16:52 | 显示全部楼层
Syc 发表于 2018-7-24 18:09
调试下看看这句 memcpy(m_pBuf + m_nWritePos, buf, count); 在内存拷贝的时候是不是目标地址为空,或者拷 ...

调试了一下这个崩溃是必现的第二次100%会崩溃

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

51_avatar_middle
online_admins Syc 发表于 2018-7-26 17:27:25 | 显示全部楼层
突突突突 发表于 2018-7-25 10:16
调试了一下这个崩溃是必现的第二次100%会崩溃

方便的话,工程代码传上来吧,我这边本地调试下看看

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-12-11 02:52

Powered by Discuz! X3.4

© 2009-2018 cctry.com

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