博客
关于我
数据结构 第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/

你可能感兴趣的文章
NO.23 ZenTaoPHP目录结构
查看>>
NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
查看>>
NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
查看>>
Node JS: < 一> 初识Node JS
查看>>
Node-RED中使用JSON数据建立web网站
查看>>
Node-RED中使用json节点解析JSON数据
查看>>
Node-RED中使用node-random节点来实现随机数在折线图中显示
查看>>
Node-RED中使用node-red-browser-utils节点实现选择Windows操作系统中的文件并实现图片预览
查看>>
Node-RED中使用node-red-contrib-image-output节点实现图片预览
查看>>
Node-RED中使用node-red-node-ui-iframe节点实现内嵌iframe访问其他网站的效果
查看>>
Node-RED中使用Notification元件显示警告讯息框(温度过高提示)
查看>>
Node-RED中实现HTML表单提交和获取提交的内容
查看>>
Node-RED中通过node-red-ui-webcam节点实现访问摄像头并截取照片预览
查看>>
Node.js 8 中的 util.promisify的详解
查看>>
Node.js 函数是什么样的?
查看>>
Node.js 历史
查看>>
Node.js 在个推的微服务实践:基于容器的一站式命令行工具链
查看>>
Node.js 实现类似于.php,.jsp的服务器页面技术,自动路由
查看>>
Node.js 异步模式浅析
查看>>
node.js 怎么新建一个站点端口
查看>>