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,也需要迭代升级,解决问题。
  • 相关阅读:
    USACO Milk2 区间合并
    Codeforces 490B Queue【模拟】
    HDU 3974 Assign the task 简单搜索
    HDU 5119 Happy Matt Friends(2014北京区域赛现场赛H题 裸背包DP)
    Cin、Cout 加快效率方法
    POJ 1159 回文LCS滚动数组优化
    POJ 2479 不相交最大子段和
    POJ 1458 最长公共子序列 LCS
    在阿里最深刻的,还是职场之道给我的震撼
    精细化
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10123468.html
Copyright © 2011-2022 走看看