zoukankan      html  css  js  c++  java
  • 数据结构开发(7):典型问题分析(Bugfix)

    0.目录

    1.创建异常对象时的空指针问题

    6.StLib 是否有必要增加多维数组类?

    1.创建异常对象时的空指针问题

    ISSUE 1——创建异常对象时的空指针问题:

    改进Exception.cpp:
    在init函数中改进strdup的赋值方法

    void Exception::init(const char* message, const char* file, int line)
    {
        /* message指向的字符串有可能在栈上,有可能在堆空间,还有可能在全局数据区
         * strdup()将字符串复制一份到堆空间中
         * file:发生异常的文件名
         * line:发生异常的行号
         * m_location的长度加2,一个给":",一个给""
         */
        m_message = (message ? strdup(message) : NULL);
    
        if( file != NULL )
        {
            char sl[16] = {0};
    
            itoa(line, sl, 10);
    
            m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + 2));
    
            if( m_location != NULL )
            {
                m_location = strcpy(m_location, file);
                m_location = strcat(m_location, ":");
                m_location = strcat(m_location, sl);
            }
        }
        else
        {
            m_location = NULL;
        }
    }
    

    ISSUE 2——LinkList 中的数据元素删除:

    单链表的实现没有考虑异常安全性!
    改进LinkList.h中的remove函数和clear函数:

        bool remove(int i)
        {
            bool ret = ((0 <= i) && (i < m_length));
    
            if( ret )
            {
                Node* current = position(i);
                Node* toDel = current->next;
    
                current->next = toDel->next;
    
                m_length--;
                
                destroy(toDel);
            }
    
            return ret;
        }
    
        void clear()
        {
            while ( m_header.next )
            {
                Node* toDel = m_header.next;
    
                m_header.next = toDel->next;
                
                m_length--;
    
                destroy(toDel);
            }
        }
    

    ISSUE 3——LinkList 中遍历操作与删除操作的混合使用:

    混合使用导致了m_current指向了已经被删除的结点,于是程序出错。
    改进LinkList.h中的remove函数:

        bool remove(int i)
        {
            bool ret = ((0 <= i) && (i < m_length));
    
            if( ret )
            {
                Node* current = position(i);
                Node* toDel = current->next;
    
                if( m_current == toDel )
                {
                    m_current = toDel->next;
                }
    
                current->next = toDel->next;
    
                m_length--;
    
                destroy(toDel);
            }
    
            return ret;
        }
    

    main.cpp测试

    #include <iostream>
    #include "LinkList.h"
    
    using namespace std;
    using namespace StLib;
    
    int main()
    {
        LinkList<int> list;
    
        for(int i=0; i<5; i++)
        {
            list.insert(i);
        }
    
        for(list.move(0); !list.end(); list.next())
        {
            if( list.current() == 3 )
            {
                list.remove(list.find(list.current()));
    
                cout << list.current() << endl;
            }
        }
    
        for(int i=0; i<list.length(); i++)
        {
            cout << list.get(i) << endl;
        }
    
        return 0;
    }
    

    运行结果为:

    4
    0
    1
    2
    4
    

    ISSUE 4——StaticLinkList 中数据元素删除时的效率问题:

    改进LinkList.h中的destroy函数:

        void destroy(Node* pn)
        {
            SNode* space = reinterpret_cast<SNode*>(m_space);
            SNode* psn = dynamic_cast<SNode*>(pn);
    
            for(int i=0; i<N; i++)
            {
                if( psn == (space + i) )
                {
                    m_used[i] = 0;
                    psn->~SNode();
                    break;
                }
            }
        }
    

    main.cpp测试

    #include <iostream>
    #include "StaticLinkList.h"
    
    using namespace std;
    using namespace StLib;
    
    int main()
    {
        StaticLinkList<int, 10> list;
    
        for(int i=0; i<5; i++)
        {
            list.insert(i);
        }
    
        list.remove(3);
    
        for(int i=0; i<list.length(); i++)
        {
            cout << list.get(i) << endl;
        }
    
        return 0;
    }
    

    运行结果为:

    0
    1
    2
    4
    

    ISSUE 5——StaticLinkList 是否需要提供析构函数?:

    构造函数与析构函数不会发生多态,于是调用的是父类的析构函数!
    改进StaticLinkList.h:
    在子类StaticLinkList中实现析构函数:

        ~StaticLinkList()
        {
            this->clear();
        }
    

    6.StLib 是否有必要增加多维数组类?

    ISSUE 6——StLib 是否有必要增加多维数组类?
    多维数组的本质:数组的数组!

    不需要定义多维数组!

    使用DynamicArray创建多维数组:

    #include <iostream>
    #include "DynamicArray.h"
    
    using namespace std;
    using namespace StLib;
    
    int main()
    {
        DynamicArray< DynamicArray<int> > d;
    
        d.resize(3);
    
        for(int i=0; i<d.length(); i++)
        {
            d[i].resize(i + 1);
        }
    
        for(int i=0; i<d.length(); i++)
        {
            for(int j=0; j<d[i].length(); j++)
            {
                d[i][j] = i * j;
            }
        }
    
        for(int i=0; i<d.length(); i++)
        {
            for(int j=0; j<d[i].length(); j++)
            {
                cout << d[i][j] << " ";
            }
    
            cout << endl;
        }
    
        return 0;
    }
    

    运行结果为:

    0 
    0 1 
    0 2 4 
    

    实践经验:

    • 是软件就有bug因此需要不停的迭代升级,解决问题。库是一种特殊的软件产品也会存在各种bug,也需要迭代升级,解决问题。
  • 相关阅读:
    7、猜年龄
    6、continue语句
    5、break语句
    4、while循环练习
    poj 2378
    poj 2342
    poj 2287
    poj 2228
    poj 1191
    srm 578 dv2 1000pt
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10123468.html
Copyright © 2011-2022 走看看