调试 nullptr 错误

调试 C++ 代码并提供说明。

在对 Cloud 控制台使用不同参数值时,或通过直接调用 Vertex AI API,您可以直接查询模型,并测试返回的结果。

系统指令

您是经验丰富的软件工程师和调试专家,对计算机科学中常用的数据结构及其应用有深入的了解。您可以向用户明确说明其代码存在的问题。

提示Freeform

如果我有一个节点表示如下所示的图表:

class GraphNode {
public:
  int val;
  std::vector<GraphNode*> adj_nei;
  GraphNode() {
    val = 0;
    adj_nei = std::vector<GraphNode*>();
  }
  GraphNode(int _val) {
    val = _val;
    adj_nei = std::vector<GraphNode*>();
  }
  GraphNode(int _val, std::vector<GraphNode*> _adj_nei) {
    val = _val;
    adj_nei = _adj_nei;
  }
};

我尝试编写一个函数,以便在此处执行深层复制:

#include <vector>
#include <map>

class GraphNodeDeepCopy {
private:
  std::map<GraphNode*, GraphNode*> v;

public:
  GraphNode* dcGraph(GraphNode* gn) {
    if (v.find(gn) != v.end()) {
      return v[gn];
    }

    GraphNode* dcGraphNode = new GraphNode(gn->val, {});
    v[gn] = dcGraphNode;

    for (GraphNode* nei : gn->adj_nei) {
      dcGraphNode->adj_nei.push_back(dcGraph(nei));
    }
    return dcGraphNode;
  }
};

这不起作用,尤其是在 gn 为 null 的情况下。您能帮忙解决这个问题吗?(此外,请合并所有代码。)

响应

所提供的代码存在一些问题:

  1. 空指针解引用:最严重的问题是在访问 gn->valgn->adj_nei 之前未对 gn 进行 null 检查。如果调用 dcGraph(nullptr),代码将崩溃。

  2. 深度复制效率低下:虽然代码尝试使用映射进行深度复制以避免冗余复制,但效率并不理想。v 映射中的重复查找可能会增加开销,尤其是对于大型图表。

以下是改进后的代码,并对更改进行了说明:

#include <vector>
#include <map>

class GraphNode {
public:
  int val;
  std::vector<GraphNode*> adj_nei;
  GraphNode() {
    val = 0;
    adj_nei = std::vector<GraphNode*>();
  }
  GraphNode(int _val) {
    val = _val;
    adj_nei = std::vector<GraphNode*>();
  }
  GraphNode(int _val, std::vector<GraphNode*> _adj_nei) {
    val = _val;
    adj_nei = _adj_nei;
  }
};

class GraphNodeDeepCopy {
private:
  std::map<GraphNode*, GraphNode*> v;

public:
  GraphNode* dcGraph(GraphNode* gn) {
    // Handle null input gracefully
    if (gn == nullptr) {
      return nullptr; 
    }

    if (v.find(gn) != v.end()) {
      return v[gn];
    }

    // Create a new node.  Note:  We don't need to initialize adj_nei here.
    GraphNode* dcGraphNode = new GraphNode(gn->val); 
    v[gn] = dcGraphNode;

    // Recursively copy the neighbors
    for (GraphNode* nei : gn->adj_nei) {
      dcGraphNode->adj_nei.push_back(dcGraph(nei));
    }
    return dcGraphNode;
  }
};

主要改进

  • 空检查:在 dcGraph 函数的开头添加 if (gn == nullptr) { return nullptr; } 可防止在传递 null 指针时发生崩溃。这对于健壮的代码至关重要。

  • 简化了构造函数用法:更高效地使用 GraphNode 构造函数。我们无需在 dcGraphNode 创建期间预先初始化 adj_nei,因为我们会在递归复制期间填充它。这会略微提高性能和可读性。

此修改后的代码解决了 null 指针解引用问题,并提供了更健壮、效率略高的深度复制函数。请注意,您需要管理 new 分配的内存(使用 delete),以免在使用完复制的图表后发生内存泄漏。考虑使用智能指针(例如,std::unique_ptrstd::shared_ptr),以便在生产环境中更好地管理内存。

型号: gemini-1.5-flash-002
温度: 0.2
输出令牌数量上限: 8192
TopK: 40.0
TopP: 0.95