博客
关于我
数据结构 第26课 典型问题分析(Bugfix)-------1----------狄泰软件学院
阅读量:261 次
发布时间:2019-03-01

本文共 4066 字,大约阅读时间需要 13 分钟。

问题1 (深入分析 strdup)

#include 
#include "Exception.h"using namespace std;using namespace DTLib;int main() { try { NullPointerException npe; cout << "throw" << endl; throw npe; } catch(const exception& e) { cout << "catch" << endl; } return 0;}

问题分析:

  • 在glibc中,strdup函数默认假设输入的字符串不为空。如果传递空指针(0),会导致堆内存泄漏。
  • Exception.h中,直接赋值m_message = message;可能导致外部字符串的生命周期控制不当。
  • 正确的做法是使用strdup复制字符串到堆空间,并检查是否为空。

解决方案:

  • 修改Exception.h中的赋值逻辑为:
    m_message = (message ? strdup(message) : NULL);
  • 这样可以确保堆内存的安全管理,避免内存泄漏。

问题2 (链表逻辑,异常安全性)

#include 
#include "LinkList.h"using namespace std;class Test : public Object { int m_id;public: Test(int id = 0) { m_id = id; } ~Test() { if(m_id == 1) { throw m_id; } }};int main() { LinkList
list; Test t0(0), t1(1), t2(2); try { list.insert(t0); list.insert(t1); list.insert(t2); list.remove(1); } catch(int e) { cout << e << endl; cout << list.length() << endl; } return 0;}

问题分析:

  • 在析构函数中抛出异常会导致编译器崩溃,因为C++不支持析构函数抛出异常。
  • remove()函数未处理异常,可能导致链表长度错误。

解决方案:

  • 检查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;}
  • clear()函数中修改为循环删除所有节点。

问题3 (LinkList 中遍历操作与删除操作的混合使用)

#include 
#include "LinkList.h"using namespace std;int main() { LinkList 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.current()); cout << list.current() << endl; } } for(list.move(0); !list.end(); list.next()) { cout << list.current() << endl; } return 0;}

问题分析:

  • 删除操作后,m_current未指向下一个节点,导致随机值问题。

解决方案:

  • 修改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;}
  • 确保删除后m_current指向下一个节点。

问题4(StaticLinkList 中数据元素删除时的效率问题)

#include 
#include "StaticLinkList.h"using namespace std;int main() { StaticLinkList
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;}

问题分析:

  • destroy()函数的逻辑存在问题,可能导致内存未正确归还。

解决方案:

  • 修改destroy()函数:
    void destroy(node* pn) {    SNode* pst = dynamic_cast
    (pn); for(int i = 0; i < n; i++) { if(pst == (space + i)) { m_used[i] = 0; pst->~SNode(); break; } }}
  • 确保内存单元归还后重新使用。

问题5(非常经典的问题)

#include 
#include "LinkList.h"#include "StaticLinkList.h"using namespace std;int main() { StaticLinkList
list; for(int i = 0; i < 5; i++) { list.insert(i); } for(int i = 0; i < 5; i++) { cout << list.get(i) << endl; } return 0;}

问题分析:

  • 子类析构函数未正确清空内存,导致内存泄漏。

解决方案:

  • 在子类中添加析构函数:
    ~StaticLinkList() {    this->clear();}
  • 确保clear()函数调用子类的destroy(),避免多态问题。

问题6(DTLib 是否有必要增加多维数组类?)

#include 
#include "DynamicArray.h"using namespace std;int main() { DynamicArray
> 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;}

问题分析:

  • 不需要添加多维数组类,因为DynamicArray支持嵌套数组。

解决方案:

  • 使用DynamicArray构造嵌套数组,实现二维功能。

以上问题通过深入分析和优化,确保了代码的健壮性和安全性。

转载地址:http://wcux.baihongyu.com/

你可能感兴趣的文章
Nodejs process.nextTick() 使用详解
查看>>
nodejs 发起 GET 请求示例和 POST 请求示例
查看>>
NodeJS 导入导出模块的方法( 代码演示 )
查看>>
nodejs 开发websocket 笔记
查看>>
nodejs 的 Buffer 详解
查看>>
nodejs 读取xlsx文件内容
查看>>
nodejs 运行CMD命令
查看>>
Nodejs+Express+Mysql实现简单用户管理增删改查
查看>>
nodejs+nginx获取真实ip
查看>>
nodejs-mime类型
查看>>
NodeJs——(11)控制权转移next
查看>>
NodeJS、NPM安装配置步骤(windows版本)
查看>>
NodeJS、NPM安装配置步骤(windows版本)
查看>>
nodejs与javascript中的aes加密
查看>>
nodejs中Express 路由统一设置缓存的小技巧
查看>>
nodejs中express的使用
查看>>
Nodejs中的fs模块的使用
查看>>
NodeJS使用淘宝npm镜像站的各种姿势
查看>>
nodejs包管理工具对比:npm、Yarn、cnpm、npx
查看>>
NodeJs单元测试之 API性能测试
查看>>