释放结构向量内存的正确方法
Correct way of freeing memory of a vector of structs
释放 struct
的 std::vector
内存的正确方法是什么?
考虑以下伪代码:
typedef struct
{
unsigned int packageLen;
unsigned char* package;
} PACKAGE;
std::vector<PACKAGE*>* packages = new std::vector<PACKAGE*>;
for (...)
{
PACKAGE *tempPackage = new PACKAGE;
// Set data of package
packages->pushback(tempPackage);
}
// Function exit
if (packages)
delete packages;
这会正确释放分配的内存吗?
Would this correctly free the assigned memory?
它会正确地释放向量的内存。
它无法正确释放 PACKAGE
个对象的内存,这些对象的指针存储在向量中。除非这些指针被复制到别处,否则这将是内存泄漏。
此外,if (packages)
检查是多余的。
动态分配向量几乎没有充分的理由。而且几乎没有充分的理由使用拥有裸指针。尽量避免这些。
经验法则:每个 new
需要 delete
在您的示例中,您使用 new
分配了矢量对象,并使用 delete
删除了它。那是对的。但是您还循环创建了许多包并且没有删除它们。为了让 C++ 为你做这件事,你必须为 std::vector
编写你自己的分配器对象,或者在删除向量之前,遍历它并删除它的项目:
for (auto &ptr : packages) delete ptr;
delete packages;
packages = nullptr;
另请注意,我将包指针设置为 nullptr
。当您使用 delete
时,这不会自行发生。虽然对 nullptr 的 delete 是幂等且安全的,但对已删除的指针调用 delete 会导致程序崩溃(您清楚地知道,考虑到最后的条件)。
**注意:** 正如@eerorika 所述,通常没有理由动态分配 std::vector
并且在现代 C++ 中,通常首选智能指针(std::unique_ptr
和 std::shared_ptr
).
不,你正在泄漏内存。这是一个正确的方法TM
struct Package
{
// ...
};
int main()
{
std::vector<Package> packages; // no pointers involved
// Can use vector::reserve at this point if you know how many
// elements you are going to need
for (...)
{
packages.push_back({ /*...*/ }); // may also add a constructor and call emplace_back
// Use packages.back() or other elements as you need
}
// No need to free anything
}
当然,您可以改进此代码以满足您的具体情况。例如,如果您确切知道要默认初始化多少个元素,则可以在构造函数中创建它们。
Would this correctly free the assigned memory?
不,您正在泄漏所有 PACKAGE
个实例,可能还有所有 char[]
个实例。在这种代码中 根本不应该有 new
或 delete
。
struct Package
{
std::string package;
};
std::vector<Package> packages;
for (...)
{
Package tempPackage;
// Set data of package
packages.push_back(tempPackage);
}
// Function exit
释放 struct
的 std::vector
内存的正确方法是什么?
考虑以下伪代码:
typedef struct
{
unsigned int packageLen;
unsigned char* package;
} PACKAGE;
std::vector<PACKAGE*>* packages = new std::vector<PACKAGE*>;
for (...)
{
PACKAGE *tempPackage = new PACKAGE;
// Set data of package
packages->pushback(tempPackage);
}
// Function exit
if (packages)
delete packages;
这会正确释放分配的内存吗?
Would this correctly free the assigned memory?
它会正确地释放向量的内存。
它无法正确释放 PACKAGE
个对象的内存,这些对象的指针存储在向量中。除非这些指针被复制到别处,否则这将是内存泄漏。
此外,if (packages)
检查是多余的。
动态分配向量几乎没有充分的理由。而且几乎没有充分的理由使用拥有裸指针。尽量避免这些。
经验法则:每个 new
delete
在您的示例中,您使用 new
分配了矢量对象,并使用 delete
删除了它。那是对的。但是您还循环创建了许多包并且没有删除它们。为了让 C++ 为你做这件事,你必须为 std::vector
编写你自己的分配器对象,或者在删除向量之前,遍历它并删除它的项目:
for (auto &ptr : packages) delete ptr;
delete packages;
packages = nullptr;
另请注意,我将包指针设置为 nullptr
。当您使用 delete
时,这不会自行发生。虽然对 nullptr 的 delete 是幂等且安全的,但对已删除的指针调用 delete 会导致程序崩溃(您清楚地知道,考虑到最后的条件)。
**注意:** 正如@eerorika 所述,通常没有理由动态分配 std::vector
并且在现代 C++ 中,通常首选智能指针(std::unique_ptr
和 std::shared_ptr
).
不,你正在泄漏内存。这是一个正确的方法TM
struct Package
{
// ...
};
int main()
{
std::vector<Package> packages; // no pointers involved
// Can use vector::reserve at this point if you know how many
// elements you are going to need
for (...)
{
packages.push_back({ /*...*/ }); // may also add a constructor and call emplace_back
// Use packages.back() or other elements as you need
}
// No need to free anything
}
当然,您可以改进此代码以满足您的具体情况。例如,如果您确切知道要默认初始化多少个元素,则可以在构造函数中创建它们。
Would this correctly free the assigned memory?
不,您正在泄漏所有 PACKAGE
个实例,可能还有所有 char[]
个实例。在这种代码中 根本不应该有 new
或 delete
。
struct Package
{
std::string package;
};
std::vector<Package> packages;
for (...)
{
Package tempPackage;
// Set data of package
packages.push_back(tempPackage);
}
// Function exit