免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: liujq110
打印 上一主题 下一主题

一个减少段错误的方法 --- [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-04-22 10:39 |只看该作者
在不考虑运行效率的情况下,用异常处理机制吧,代码简洁

论坛徽章:
0
12 [报告]
发表于 2009-04-22 11:17 |只看该作者
肯定是有的 malloc 在 if 内, 没执行。

论坛徽章:
0
13 [报告]
发表于 2009-04-22 16:09 |只看该作者
用if判断会改变程序的行为,原本有可能触发空指针bug的情形就走不到了。
你应该用assert断言空指针,这样才能重现错误,而不是绕开或掩盖错误。

论坛徽章:
0
14 [报告]
发表于 2009-04-22 16:15 |只看该作者
你是不是还得判断
p == 0x01
p == 0x02
p == 0x03
.......
.......
.......

论坛徽章:
0
15 [报告]
发表于 2009-04-22 16:27 |只看该作者
这种做法是在规避问题,不是在解决问题,也许某一天它就爆发了。。

论坛徽章:
0
16 [报告]
发表于 2009-04-22 16:34 |只看该作者
加入判断是必须的。
比如free( p )之后,p所指示的内存块确实释放了,但是p确不一定是NULL。
它可能指到内存的某个其它地方。而这些地方如果正在被是有,那就段错误了。

所以好的code不仅要判断,还要在每次free之后在加入一句p = NULL来防止错误。

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
17 [报告]
发表于 2009-04-22 16:46 |只看该作者
我早上上班的时候,闻到房间里有焦糊味,好像哪里着火了。
找了半天也没找到,就搞了几床被子,把冰箱电视电脑电炉什么的都盖上了,竟然就闻不到焦味了。不知此法怎样,呵呵

论坛徽章:
0
18 [报告]
发表于 2009-04-22 20:46 |只看该作者
呵呵  是要面对问题 而不是要掩盖问题  

可能是我的程序设计的想法就不对 说出来请大牛们指点指点

论坛徽章:
0
19 [报告]
发表于 2009-04-22 21:33 |只看该作者

malloc 和 free 在不同的线程中

我想写一个线程池,他有一个管理线程用来增减线程和查看线程是否仍然存在,还有n个子线程,是干活的。
子线程起来后执行回调函数(其他类的静态函数)。
写这个线程池的目的就是可以用这个线程池来干任意用到多线程的活(干什么活通过回调函数指定)

下面说一下我的测试(用来接收和发送)


        //线程池入参结构体
        typedef struct ThreadPoolarg
        {
                void        *(*Child_process)(void *Child_arg);//子线程的回调函数
                void        *ThreadPoolSelf;  //线程池自身实例对象的地址
                void        *ThreadPoolOther; //该线程池另一个实例对象的地址
                void        *SocketMap;       //用到的socket集合
                int        Min_No;             //最大线程数
                int        Max_No;                                                        //最小线程数(都是指子线程)
                int        SerialNo;                                                //线程起来是给分配的序号(for (i = 0; i < Max_No; i++) i 的值)
        }ThreadPoolarg;

main() //主进程类的main()
{
        //建立发送线程池
        CPUB_ThreadPoll        m_SendThreadPoll;
        ThreadPoolarg m_SendThreadPoolarg;  //入参结构体定义

        m_SendThreadPoolarg.Child_process = CDBProxyServer::StartSendResulit;
        m_SendThreadPoolarg.ThreadPoolSelf = (void *)&m_SendThreadPoll;
        //m_SendThreadPoolarg.ThreadPoolOther =
        m_SendThreadPoolarg.SocketMap = (void *)&m_MapServer;
        m_SendThreadPoolarg.Min_No = 8;
        m_SendThreadPoolarg.Max_No = 5;

        m_SendThreadPoll.Init_Pool((void *)&m_SendThreadPoolarg);//线程初初始化
        sleep(1);

        //建立接收线程池
        CPUB_ThreadPoll m_RecvThreadPoll;
        ThreadPoolarg m_RecvThreadPoolarg;  //入参结构体定义

        m_RecvThreadPoolarg.Child_process = CDBProxyServer::StartRecvServer;
        m_RecvThreadPoolarg.ThreadPoolSelf = (void *)&m_RecvThreadPoll;//
        m_RecvThreadPoolarg.ThreadPoolOther = (void *)&m_SendThreadPoll;
        m_RecvThreadPoolarg.SocketMap = (void *)&m_MapServer;
        m_RecvThreadPoolarg.Min_No                 = 8;
        m_RecvThreadPoolarg.Max_No                 = 5;

        m_RecvThreadPoll.Init_Pool((void *)&m_RecvThreadPoolarg);
        sleep(1);

        //建立SocketServer监听线程
        //监听端参数结构体
        typedef        struct        Listenarg
        {
                void *MapServer; //socket集合
                void        *ThreadPool; //这个是那个接收线程池实例的对象,有可读事件就将socket加入到
                                                                                                //接收线程池的链表中
                int        Port;                                                //端口号
                int UP_Linkcount;   //允许客户端连接的最大个数
        }Listenarg;

        Listenarg        m_Listenarg;//Listen 端
        m_Listenarg.MapServer = (void *)&m_MapServer;
        m_Listenarg.ThreadPool        =        (void        *)&m_RecvThreadPoll;
        m_Listenarg.Port = g_SysParameter.PS_Port;
        m_Listenarg.UP_Linkcount = g_SysParameter.PS_UPLinkcount;
        CTHD_SocketServer m_SocketServer((void *)&m_Listenarg);   //单独起的一个线程

        while(1)
        {
                sleep(1000000);        
        }
}

        //socket结构
        typedef        struct        SocketInfo
        {
                long Marker;//socket唯一标识(0~10000000之间循环)
                int Socket; //socket号
        }SocketInfo;

        测试过程是这样的:所有线程起来之后,监听端检测到有可读事件的socket
        这样做
        SocketInfo *m_SocketInfo = (SocketInfo *) malloc(sizeof(SocketInfo));
        m_SocketInfo->Marker = TempMarker;
        m_SocketInfo->Socket = events.data.fd;

        m_ThreadPoll->Add_work(5, m_SocketInfo);//将socket结构地址指针加入到线程池链表中
                                                                    //并通知接收线程池子线程:Add_work()里实现
        //接收线程池
        typedef struct ResultInf
        {
                long Marker;
                int Socket;
                char Str[1024];
        }ResultInf;

        接收线程池子线程pthread_cond_wait();          接到通知

        void *Worker = NULL;
        ret        =        (m_ThreadPoolSelf->Get_work(SerialNo, &Worker));//获得线程池链表中socket结构地址

        m_SocketInfo = (SocketInfo *)Worker;
        
        ResultInf *R_ResultInf = NULL;
        R_ResultInf = (ResultInf *) malloc (sizeof(ResultInf));

        R_ResultInf->Marker = m_SocketInfo->Marker;
        R_ResultInf->Socket        = m_SocketInfo->Socket;

        RecvCount = recv(R_ResultInf->Socket, R_ResultInf->Str, 1024, 0);
        free(Worker); //feee掉之前malloc
        m_ThreadPoolOther->Add_work(5, R_ResultInf);//将接收的结果加入到发送线程池
                                                                        //  m_ThreadPoolOther
        //发送线程池
        void *Worker = NULL;
        ResultInf *m_ResultInf = NULL;
        ret        =        (m_ThreadPoolSelf->Get_work(SerialNo, &Worker)); //获得接收结果结构地址之争
        m_ResultInf = (ResultInf *)Worker;
        SendCount = m_RecvSendServer.SendServer(m_ResultInf->Socket,        m_ResultInf->Str,        1024);
        
        free(Worker);//free掉之前malloc

[ 本帖最后由 liujq110 于 2009-4-22 21:41 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
20 [报告]
发表于 2009-04-22 21:44 |只看该作者
我觉得这种方法很好!
软件是有生命周期的,员工劳动合同是有合同期的,
何必把自己搞的太累呢。

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

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP