C++ c++;删除后的指针仍占用内存 clear()在很大程度上是毫无意义和无关的。无论你做什么,向量通常都不会收缩。即使他们这么做了,你还是要删除它

C++ c++;删除后的指针仍占用内存 clear()在很大程度上是毫无意义和无关的。无论你做什么,向量通常都不会收缩。即使他们这么做了,你还是要删除它,c++,C++,这是我的代码: #include <iostream> #include <vector> int main() { std::vector<int*> * data = new std::vector<int*>; for (int i = 0; i < 1000; i++) { data->push_back(new int[100000]); } for (int i = 0;

这是我的代码:

#include <iostream>
#include <vector>

int main() {
    std::vector<int*> * data = new std::vector<int*>;

    for (int i = 0; i < 1000; i++) {
        data->push_back(new int[100000]);
    }

    for (int i = 0; i < 100; i++) {
        delete data->at(i);
    }

    data->clear();
    delete data;
    data = nullptr;
    return 0;
}
这不会改变任何事情


我的问题是,如何才能完全删除指针并释放内存?

首先,您可能并没有真正删除所有内容。你只循环到100,你推了1000个项目。其次,使用
data->clear()
在很大程度上是毫无意义和无关的。无论你做什么,向量通常都不会收缩。即使他们这么做了,你还是要删除它

最后,不要使用
new
delete
,要谨慎使用原始指针。如果你一开始没有使用它们,你就不会犯你所犯的错误。你应该这样做:

#include <iostream>
#include <vector>
#include <memory>

int main() {
    using ::std::make_unique;
    using ::std::unique_ptr;
    typedef unique_ptr<int []> ary_el_t;
    auto data = make_unique<::std::vector<ary_el_t>>();

    for (int i = 0; i < 1000; i++)
    {
        data->push_back(make_unique<int[]>(100000));
    }

    data.reset();

    return 0;
}
#包括
#包括
#包括
int main(){
使用::std::使_唯一;
使用::std::unique_ptr;
typedef唯一存储单元;
自动数据=使_唯一();
对于(int i=0;i<1000;i++)
{
数据->推回(使_唯一(100000));
}
data.reset();
返回0;
}
而且,即使你这样做了,你可能仍然无法恢复记忆。当要求分配更多空间时,分配器将重用释放的空间,但它们通常不会将其返回到操作系统


上面的代码确实需要C++14才能工作。但VisualStudio的最新版本应该支持这一点。我在我的Linux机器上用g++测试了这一点,我的分配器确实会将内存返回到操作系统,因此我能够验证所有的取消分配是否确实有效。

首先,您可能没有真正删除所有内容。你只循环到100,你推了1000个项目。其次,使用
data->clear()
在很大程度上是毫无意义和无关的。无论你做什么,向量通常都不会收缩。即使他们这么做了,你还是要删除它

最后,不要使用
new
delete
,要谨慎使用原始指针。如果你一开始没有使用它们,你就不会犯你所犯的错误。你应该这样做:

#include <iostream>
#include <vector>
#include <memory>

int main() {
    using ::std::make_unique;
    using ::std::unique_ptr;
    typedef unique_ptr<int []> ary_el_t;
    auto data = make_unique<::std::vector<ary_el_t>>();

    for (int i = 0; i < 1000; i++)
    {
        data->push_back(make_unique<int[]>(100000));
    }

    data.reset();

    return 0;
}
#包括
#包括
#包括
int main(){
使用::std::使_唯一;
使用::std::unique_ptr;
typedef唯一存储单元;
自动数据=使_唯一();
对于(int i=0;i<1000;i++)
{
数据->推回(使_唯一(100000));
}
data.reset();
返回0;
}
而且,即使你这样做了,你可能仍然无法恢复记忆。当要求分配更多空间时,分配器将重用释放的空间,但它们通常不会将其返回到操作系统


上面的代码确实需要C++14才能工作。但VisualStudio的最新版本应该支持这一点。我在我的Linux机器上用g++测试了这一点,我的分配器确实会将内存返回到操作系统,因此我能够验证所有的取消分配是否确实有效。

你推
1000次,删除
100次,这是故意的吗?任务管理器不是检测内存泄漏的一种方法。此外,大多数内存管理器不会在释放内存时立即将内存释放回操作系统,因为它们假定您将再次使用它。
new[]
应该通过
delete[]
来平衡。此外,您几乎不应该使用
new[]
delete[]
任何方式。您可以试着打电话看看是否有帮助。您误解了delete的作用。它允许您的程序再次使用内存,不允许其他程序再次使用内存。因此,任务管理器仍然显示您的程序具有内存。您正在按
1000次
并删除
100次
,这是故意的吗?任务管理器不是检测内存泄漏的一种方法。此外,大多数内存管理器不会在释放内存时立即将内存释放回操作系统,因为它们假定您将再次使用它。
new[]
应该通过
delete[]
来平衡。此外,您几乎不应该使用
new[]
delete[]
任何方式。您可以试着打电话看看是否有帮助。您误解了delete的作用。它允许您的程序再次使用内存,不允许其他程序再次使用内存。因此任务管理器仍然显示您的程序具有内存是正确的。感知有时是一件奇怪的事情。即使我写了
data->reset
我也认为它是
清晰的
。写
时尽量少用原始指针也不一定正确。如果要保留或转移所有权,请使用智能指针;如果只想传递当前使用的对象,请使用引用或原始指针。因此,对于大多数传递对象的实用函数,不会通过智能指针传递对象,而是通过其原始指针或引用是正确的。感知有时是一件奇怪的事情。即使我写了
data->reset
我也认为它是
清晰的
。写
时尽量少用原始指针也不一定正确。如果要保留或转移所有权,请使用智能指针;如果只想传递当前使用的对象,请使用引用或原始指针。因此,对于大多数传递对象的实用函数,不会通过智能指针传递对象,而是通过其原始指针或引用。
delete data;
data = nullptr;
#include <iostream>
#include <vector>
#include <memory>

int main() {
    using ::std::make_unique;
    using ::std::unique_ptr;
    typedef unique_ptr<int []> ary_el_t;
    auto data = make_unique<::std::vector<ary_el_t>>();

    for (int i = 0; i < 1000; i++)
    {
        data->push_back(make_unique<int[]>(100000));
    }

    data.reset();

    return 0;
}