【问题标题】:How to properly delete those pointers?如何正确删除这些指针?
【发布时间】:2019-03-14 18:33:38
【问题描述】:

这是我的分配:

for (int i = 0; i < numCols; i++)
{
    columnNameLen = new SQLSMALLINT *[numCols];
    columnDataType = new SQLSMALLINT *[numCols];
    columnDataSize = new SQLULEN *[numCols];
    columnDataDigits = new SQLSMALLINT *[numCols];
    columnDataNullable = new SQLSMALLINT *[numCols];
    columnData = new SQLWCHAR *[numCols];
    columnDataLen = new SQLLEN *[numCols];
    columnName = new SQLWCHAR *[numCols];
}

for (int i = 0; i < numCols; i++)
{
    columnNameLen[i] = new SQLSMALLINT;
    columnDataType[i] = new SQLSMALLINT;
    columnDataSize[i] = new SQLULEN;
    columnDataDigits[i] = new SQLSMALLINT;
    columnDataNullable[i] = new SQLSMALLINT;
    columnDataLen[i] = new SQLLEN;
    columnName[i] = new SQLWCHAR[256];
}

这是我的删除:

for (int i = 0; i < numCols; i++)
{
    delete columnNameLen[i];
    columnNameLen[i] = NULL;
    delete columnDataType[i];
    columnDataType[i] = NULL;
    delete columnDataSize[i];
    columnDataSize[i] = NULL;
    delete columnDataDigits[i];
    columnDataDigits[i] = NULL;
    delete columnDataNullable[i];
    columnDataNullable[i] = NULL;
    delete columnData[i];
    columnData[i] = NULL;
    delete columnDataLen[i];
    columnDataLen[i] = NULL;
    delete[] columnName[i];
    columnName[i] = NULL;
}

for (int i = 0; i < numCols; i++)
{
    delete[] columnNameLen;
    columnNameLen = NULL;
    delete[] columnDataType;
    columnDataType = NULL;
    delete[] columnDataSize;
    columnDataSize = NULL;
    delete[] columnDataDigits;
    columnDataDigits = NULL;
    delete[] columnDataNullable;
    columnDataNullable = NULL;
    delete[] columnData;
    columnData = NULL;
    delete[] columnDataLen;
    columnDataLen = NULL;
    delete[] columnName;
    columnName = NULL;
}

上面的代码可以吗?我可能应该只使用智能指针,但我不知道使用它们的代码会是什么样子?因此,如果您输入智能指针代码,将不胜感激。这些指针在线程函数中本地使用,不与任何东西共享。

我担心第二个循环只需要delete 而不是delete[]

TIA!

【问题讨论】:

  • 开始使用 c++ 惯用的结构,你永远不会后悔。 std::vector、std::shared_ptr 和 std::string(不清楚是否已经使用)
  • 这些东西是二维的吗?为什么不只是new SQLSMALLINT [numCols]
  • @pm100,是的,它是二维的。
  • @pm100,shared_ptr 会是什么样子?
  • 你确定是 2D,我想你只有一个 columnNameLen、columnDataType、...的数组,你首先代码分配了许多数组,但只使用其中一个(对于每个 columnNameLen,... )

标签: c++ c++11 pointers smart-pointers


【解决方案1】:

你不应该在这里使用指针

using SQLSTRING = std::basic_string<SQLWCHAR>;

struct Column
{
    SQLSTRING Name;
    SQLSTRING Data;
    SQLSMALLINT DataType;
    SQLULEN DataSize;
    SQLSMALLINT DataDigits;
    SQLSMALLINT DataNullable;
}

std::vector<Column> columns(numCols);

【讨论】:

  • 这就是为什么我询问是否真的需要 2D,但 OP 说“是的,它们应该是 2D”。
  • @Caleth,该代码用于在获取实际数据之前检索数据库结果信息。我认为使用 std::vector 对于 sch 简单任务来说只是一种矫枉过正。特别是,因为为了从游标中检索数据,代码将非常难看: SQLGetData( m_hstmt, 1, columns.DataType.at( 0 ),.....);但这是我的看法。
  • @Igor 完全错误的 std:vector 正在简单而正确地做你没有成功的事情
  • @Igor std::vector默认 容器。忘记 C 样式数组的存在,忘记 new 的存在
  • @Igor 的用法并没有太大的不同:[] 介于 columnsDataType 之间,并且您有引用而不是指针。例如SQLGetData( m_hstmt, 1, columnDataType[0],.....) -> SQLGetData( m_hstmt, 1, &amp;columns[0].DataType,.....)
【解决方案2】:

不要在用户代码中使用newdelete。使用std::vector&lt;&gt;

关于newdelete

使用new 分配的所有对象都必须由delete 释放,
所有使用new[] 分配的对象都必须由delete[] 释放。

还要确保您关注Rule of 3/5。 (如果您不使用智能指针或其他遵循 RAII/RDID 的对象来包装原始拥有指针,那么您应该瞄准的 Rule of 0 ... 是毫无疑问的)。

【讨论】:

    【解决方案3】:

    您的代码正在泄漏内存,因为在您的第一个循环中,您一次又一次地覆盖相同的指针(丢失先前的值并且这永远不会释放它)。

    对于释放,第二个循环是不必要的。这将避免您第一次删除指针和下一次迭代尝试删除 nullptr。

    顺便说一句:

    • 使用 nullptr 代替 NULL
    • 您也可以使用 shared_ptr 或 unique_ptr 来代替原始指针。
    • 如果可行,请使用向量而不是数组。

    【讨论】:

      【解决方案4】:

      如果您不能放弃指针(有时没有其他方法)并且也不想要任何建议的替代方案,请考虑使用SCOPE_EXIT 相似,例如Boost.ScopeExit。然后,您可以执行以下操作:

      SCOPE_EXIT(p, delete p);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-01
        • 1970-01-01
        • 2017-09-19
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        • 1970-01-01
        相关资源
        最近更新 更多