From 9ca199497985c526c31e8884f6911fd49be6b807 Mon Sep 17 00:00:00 2001
From: shiyb <ninthozward1@outlook.com>
Date: 星期一, 19 五月 2025 17:07:39 +0800
Subject: [PATCH] Merge branch 'master' of ssh://117.78.1.188:29418/test-upload 修改了错误示例

---
 /dev/null             |    6 -
 Test/errorexample.cpp |  267 +++++++++++++++++++++++++++++++++++++++--------------
 Test/errorexample.h   |   12 +-
 Test/Test.pro         |    2 
 4 files changed, 201 insertions(+), 86 deletions(-)

diff --git a/Test/Test.pro b/Test/Test.pro
index afe781a..d2d73c4 100644
--- a/Test/Test.pro
+++ b/Test/Test.pro
@@ -17,13 +17,11 @@
 
 SOURCES += \
     errorexample.cpp \
-    linestyle.cpp \
     main.cpp \
     mainwindow.cpp
 
 HEADERS += \
     errorexample.h \
-    linestyle.h \
     mainwindow.h
 
 FORMS += \
diff --git a/Test/errorexample.cpp b/Test/errorexample.cpp
index e3c828a..0cd7a52 100644
--- a/Test/errorexample.cpp
+++ b/Test/errorexample.cpp
@@ -1,105 +1,228 @@
 #include "errorexample.h"
 
+#include <QFile>
 #include <QLabel>
+#include <QPushButton>
 errorexample::errorexample() {
   // 1.未包含必要的头文件
   // 错误:缺少 #include <QLabel>
   QLabel label("Hello");  // 编译错误:'QLabel' was not declared in this scope
   label.show();
 
-  // 2.未初始化指针
-  QLabel *label4;
-  label4->setText("Hello");  // 错误:使用未初始化的指针
+  //-----------指针常见问题---------------
 
-  // 修复:初始化指针
-  QLabel *label5 = new QLabel;
+  //①空指针解引用
+  QWidget *widget = nullptr;
+  widget->show();  //对值为nullptr的指针进行访问操作,会引发崩溃
 
-  // 3.父对象管理不当导致内存泄露
-  QLabel *label1 = new QLabel("Memory Leak");
-  label1->show();
+  //解决办法:
+  QWidget *widget1 = nullptr;
+  if (widget1) {  //使用指针前,先确认其是否为nullptr
+    widget1->show();
+  }
 
-  // 正确做法:设置父对象,Qt会自动管理内存
+  //②野指针
+  //指针所指向的内存已经被释放,但后续仍在使用该指针
+  QWidget *widget2 = new QWidget;
+  delete widget2;
+  widget2->show();  //此时widget2已经变成野指针
+
+  //解决办法:
+  //对象释放之后,及时将指针置为nullptr(利用 Qt
+  //对象的父子关系机制来自动管理内存)
+  QWidget *widget3 = new QWidget;
+  delete widget3;
+  widget3 = nullptr;  //避免野指针
+
+  //③内存泄露:未释放动态分配的内存
+  void createLeak() {
+    int *ptr = new int(10);  //分配后未释放
+  }
+  //解决办法:
+  void createLeak() {
+    int *ptr = new int(10);  //分配后未释放
+    delete ptr;
+    ptr = nullptr;
+  }
+
+  //④父子关系误用
   QWidget *parent = new QWidget;
-  QLabel *managedLabel = new QLabel("Managed", parent);
+  QPushButton *button = new QPushButton(parent);
+  delete button;  // 手动删除子对象
+  delete parent;  // 崩溃!父对象试图再次删除已释放的 button
 
-  // 4.使用已删除的对象
-  QLabel *label2 = new QLabel("Delete Me");
-  delete label2;
+  //解决办法:依赖对象树自动管理
+  QWidget *parent2 = new QWidget;
+  QPushButton *button2 = new QPushButton(parent);
+  delete parent2;  // 自动删除所有子对象(包括 button)
 
-  // 错误:访问已删除的对象
-  label2->setText("Oops");  // 未定义行为
+  //⑤智能指针与对象树冲突
+  //混合使用父对象和智能指针
+  QWidget *parent3 = new QWidget;
+  // 错误:父对象已管理 button,智能指针会导致双重释放
+  std::unique_ptr<QPushButton> button3(new QPushButton(parent));
 
-  // 5.字符串编码问题
-  QLabel *label3 = new QLabel;
-  // 错误:硬编码非ASCII字符串
-  label3->setText("中文文本");  // 可能显示乱码,取决于源文件编码
+  //解决办法1:仅用父对象管理
+  QWidget *parent4 = new QWidget;
+  QPushButton *button4 = new QPushButton(parent4);  // 父对象负责释放
 
-  // 正确做法:使用tr()进行翻译
-  label3->setText(tr("中文文本"));
+  //解决办法2:无父对象时使用智能指针
+  std::unique_ptr<QPushButton> button5 = std::make_unique<QPushButton>();
 
-  // 6.容器越界访问
-  QList<int> list = {1, 2, 3};
-
-  // 错误:越界访问
-  int value = list[3];  // 索引最大为2
-
-  // 正确做法:使用at()并检查边界
-  if (list.size() > 3) {
-    int safeValue = list.at(3);  // at()会在越界时抛出异常
+  //⑥容器中的指针管理
+  // 忘记释放files数组及其中的指针所指向的内存
+  QFile *files = new QFile[10];
+  for (int i = 0; i < 10; ++i) {
+    files[i].setFileName("file" + QString::number(i));
   }
 
-  // 7.缺失终止条件的For循环
-  for (int i = 0;; i++) {  // 错误:无终止条件
-                           //循环体
+  //解决办法:
+  QFile **files1 = new QFile *[10];
+  for (int i = 0; i < 10; ++i) {
+    files[i].setFileName("file" + QString::number(i));
+  }
+  for (int i = 0; i < 10; ++i) {
+    delete files1[i];
+  }
+  delete[] files;
+
+  //-----------常见逻辑错误---------------
+
+  //①无限循环
+  //错误:(无终止条件)
+  for (int i = 0; i < 10;) {
+    qDebug() << "Looping...";
+    // 忘记写i++
   }
 
-  // 正确写法:
-  for (int i = 0; i < 10; i++) {  // 添加终止条件
-                                  //循环体
+  //错误:死循环(条件恒为真)
+  while (true) {
+    //代码块          未提供退出机制
   }
 
-  // 8.误用 = 代替 ==
-  if (x = 5) {  // 误将赋值操作当作比较,条件始终为 true(除非 x 是布尔类型)
-                // ...
+  //解决办法
+  // 增加i++
+  for (int i = 0; i < 10; i++) {
+    qDebug() << "Looping..." << i;
   }
 
-  // 9.事件处理未调用基类实现
-  void CustomWidget::paintEvent(QPaintEvent * event) {
-    // 错误:未调用基类实现
-    QPainter painter(this);
-    // 缺少:QWidget::paintEvent(event);
+  //使用break或return退出循环
+  while (true) {
+    if (data.isEmpty()) break;  // 条件满足时退出
   }
 
-  // 10.信号槽参数不匹配
-  // 错误:信号参数与槽参数类型不匹配
-  connect(sender, &Sender::valueChanged(int), receiver,
-          &Receiver::updateValue(QString));
+  //②数据/容器越界访问
+  // 错误:访问越界(索引0~9,但循环到i=10)
+  QVector<int> numbers(10);
+  for (int i = 0; i <= 10; ++i) {  // 应为i < 10
+    numbers[i] = i;                // i=10时越界
+    // 错误:使用空容器
+    QStringList names;
+    qDebug() << names[0];  // 访问空容器的第一个元素
 
-  // 修复:确保参数类型一致
-  connect(sender, &Sender::valueChanged(int), receiver,
-          &Receiver::updateValue(int));
+    //解决办法
+    //使用安全的访问方法(如at()代替[])
+    qDebug() << numbers.at(10);
+    //检查容器是否为空
+    if (!names.isEmpty()) {
+      qDebug() << names[0];
+    }
 
-  // 11.未实现纯虚函数
-  class MyInterface {
-   public:
-    virtual void pureVirtual() = 0;
-  };
+    // 2.未初始化指针
+    QLabel *label4;
+    label4->setText("Hello");  // 错误:使用未初始化的指针
 
-  class MyClass : public MyInterface {
-    // 错误:未实现纯虚函数
-  };
+    // 修复:初始化指针
+    QLabel *label5 = new QLabel;
 
-  // 修复:实现纯虚函数
-  void MyClass::pureVirtual() { /* 实现 */
+    // 3.父对象管理不当导致内存泄露
+    QLabel *label1 = new QLabel("Memory Leak");
+    label1->show();
+
+    // 正确做法:设置父对象,Qt会自动管理内存
+    QWidget *parent = new QWidget;
+    QLabel *managedLabel = new QLabel("Managed", parent);
+
+    // 4.使用已删除的对象
+    QLabel *label2 = new QLabel("Delete Me");
+    delete label2;
+
+    // 错误:访问已删除的对象
+    label2->setText("Oops");  // 未定义行为
+
+    // 5.字符串编码问题
+    QLabel *label3 = new QLabel;
+    // 错误:硬编码非ASCII字符串
+    label3->setText("中文文本");  // 可能显示乱码,取决于源文件编码
+
+    // 正确做法:使用tr()进行翻译
+    label3->setText(tr("中文文本"));
+
+    // 6.容器越界访问
+    QList<int> list = {1, 2, 3};
+
+    // 错误:越界访问
+    int value = list[3];  // 索引最大为2
+
+    // 正确做法:使用at()并检查边界
+    if (list.size() > 3) {
+      int safeValue = list.at(3);  // at()会在越界时抛出异常
+    }
+
+    // 7.缺失终止条件的For循环
+    for (int i = 0;; i++) {  // 错误:无终止条件
+                             //循环体
+    }
+
+    // 正确写法:
+    for (int i = 0; i < 10; i++) {  // 添加终止条件
+                                    //循环体
+    }
+
+    // 8.误用 = 代替 ==
+    if (x = 5) {  // 误将赋值操作当作比较,条件始终为 true(除非 x 是布尔类型)
+                  // ...
+    }
+
+    // 9.事件处理未调用基类实现
+    void CustomWidget::paintEvent(QPaintEvent * event) {
+      // 错误:未调用基类实现
+      QPainter painter(this);
+      // 缺少:QWidget::paintEvent(event);
+    }
+
+    // 10.信号槽参数不匹配
+    // 错误:信号参数与槽参数类型不匹配
+    connect(sender, &Sender::valueChanged(int), receiver,
+            &Receiver::updateValue(QString));
+
+    // 修复:确保参数类型一致
+    connect(sender, &Sender::valueChanged(int), receiver,
+            &Receiver::updateValue(int));
+
+    // 11.未实现纯虚函数
+    class MyInterface {
+     public:
+      virtual void pureVirtual() = 0;
+    };
+
+    class MyClass : public MyInterface {
+      // 错误:未实现纯虚函数
+    };
+
+    // 修复:实现纯虚函数
+    void MyClass::pureVirtual() { /* 实现 */
+    }
+
+    // 12.未正确实现拷贝构造函数
+    class MyClass1 {
+     public:
+      QWidget *widget;
+      MyClass1(const MyClass1 &other) {
+        widget = other.widget;
+      }  // 错误:浅拷贝
+    };
+
+    // 修复:深拷贝或禁用拷贝构造函数
+    MyClass1(const MyClass1 &other) = delete;
   }
-
-  // 12.未正确实现拷贝构造函数
-  class MyClass1 {
-   public:
-    QWidget *widget;
-    MyClass1(const MyClass1 &other) { widget = other.widget; }  // 错误:浅拷贝
-  };
-
-  // 修复:深拷贝或禁用拷贝构造函数
-  MyClass1(const MyClass1 &other) = delete;
-}
diff --git a/Test/errorexample.h b/Test/errorexample.h
index 3a439c6..672ece8 100644
--- a/Test/errorexample.h
+++ b/Test/errorexample.h
@@ -3,11 +3,11 @@
 
 #include <QObject>
 
-class errorexample
-{
-    Q_OBJECT
-public:
-    errorexample();
+class errorexample {
+  Q_OBJECT
+ public:
+  errorexample();
+  void createLeak();
 };
 
-#endif // ERROREXAMPLE_H
+#endif  // ERROREXAMPLE_H
diff --git a/Test/linestyle.cpp b/Test/linestyle.cpp
deleted file mode 100644
index f35e83f..0000000
--- a/Test/linestyle.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "linestyle.h"
-
-linestyle::linestyle()
-{
-
-}

--
Gitblit v1.9.1