std::allocator 解除分配不使用大小参数
std::allocator deallocate don't use size argument
我正在了解 std::allocator
。我尝试分配但错误地使用 deallocate 我看到它没有使用大小参数,我对这个方法感到困惑,你能为我解释一下吗?谢谢。
- testcase1“测试”:我没有解除分配,检测到 valgrind(正确)
- testcase2“test_deallocate”:我释放了小于实际大小 (400) 的大小 (0),valgrind 或
-fsanitize=address
无法检测到泄漏
- testcase3“test_deallocate2”:我释放大小(10000)大于实际大小(400)编译器没有警告,g++
-fsanitize=address
也无法检测到这一点。
#include <iostream>
#include <memory>
using namespace std;
void test(){
allocator<int> al;
int* bl = al.allocate(100);
}
void test_deallocate(){
allocator<int> al;
int* bl = al.allocate(100);
al.deallocate(bl, 0);
}
void test_deallocate2(){
allocator<int> al;
int* bl = al.allocate(100);
al.deallocate(bl, 10000);
}
int main(){
test();
test_deallocate();
test_deallocate2();
return 0;
}
瓦尔格林德:
valgrind --leak-check=full ./a.out
==12655== Memcheck, a memory error detector
==12655== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12655== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==12655== Command: ./a.out
==12655==
==12655==
==12655== HEAP SUMMARY:
==12655== in use at exit: 400 bytes in 1 blocks
==12655== total heap usage: 4 allocs, 3 frees, 73,904 bytes allocated
==12655==
==12655== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12655== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12655== by 0x1090D1: allocate (new_allocator.h:114)
==12655== by 0x1090D1: test (test.cpp:8)
==12655== by 0x1090D1: main (test.cpp:27)
==12655==
==12655== LEAK SUMMARY:
==12655== definitely lost: 400 bytes in 1 blocks
==12655== indirectly lost: 0 bytes in 0 blocks
==12655== possibly lost: 0 bytes in 0 blocks
==12655== still reachable: 0 bytes in 0 blocks
==12655== suppressed: 0 bytes in 0 blocks
==12655==
==12655== For lists of detected and suppressed errors, rerun with: -s
==12655== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
- testcase2 "test_deallocate" : I deallocate with size(0) less than actual size (400),valgrind or -fsanitize=address can't detect leak
当你分配错误的大小时,程序的行为是未定义的。当行为未定义时,无法保证内存会泄漏。
- testcase3 "test_deallocate2": I deallocate with size(10000) greater than actual size (400) compiler didn't warning , g++ with -fsanitize=address also can't detect this.
同上。
Valgrind 仅拦截较低级别的分配函数(malloc、new 等)。所以这完全取决于 allocate
和 deallocate
的实现。
目前 Valgrind 没有对大小删除做太多检查(或对齐新的,参见 and https://bugs.kde.org/show_bug.cgi?id=433859)。
我可能会在 2022 年为这些实现一些东西。
如果您使用 GCC libstdc++ 或 clang libc++,那么它们的大小删除不会执行任何特殊操作,它们只是调用普通删除。我还没找 deallocate
.
我检查了测试用例中使用的 libstdc++。
我看到 std::allocator::deallocate 的当前大小参数未使用。它调用删除,与new/delete运算符操作相同,它不再需要大小。
00096 void
00097 deallocate(pointer __p, size_type)
00098 { ::operator delete(__p); }
https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00958_source.html
我正在了解 std::allocator
。我尝试分配但错误地使用 deallocate 我看到它没有使用大小参数,我对这个方法感到困惑,你能为我解释一下吗?谢谢。
- testcase1“测试”:我没有解除分配,检测到 valgrind(正确)
- testcase2“test_deallocate”:我释放了小于实际大小 (400) 的大小 (0),valgrind 或
-fsanitize=address
无法检测到泄漏 - testcase3“test_deallocate2”:我释放大小(10000)大于实际大小(400)编译器没有警告,g++
-fsanitize=address
也无法检测到这一点。
#include <iostream>
#include <memory>
using namespace std;
void test(){
allocator<int> al;
int* bl = al.allocate(100);
}
void test_deallocate(){
allocator<int> al;
int* bl = al.allocate(100);
al.deallocate(bl, 0);
}
void test_deallocate2(){
allocator<int> al;
int* bl = al.allocate(100);
al.deallocate(bl, 10000);
}
int main(){
test();
test_deallocate();
test_deallocate2();
return 0;
}
瓦尔格林德:
valgrind --leak-check=full ./a.out
==12655== Memcheck, a memory error detector
==12655== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12655== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==12655== Command: ./a.out
==12655==
==12655==
==12655== HEAP SUMMARY:
==12655== in use at exit: 400 bytes in 1 blocks
==12655== total heap usage: 4 allocs, 3 frees, 73,904 bytes allocated
==12655==
==12655== 400 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12655== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==12655== by 0x1090D1: allocate (new_allocator.h:114)
==12655== by 0x1090D1: test (test.cpp:8)
==12655== by 0x1090D1: main (test.cpp:27)
==12655==
==12655== LEAK SUMMARY:
==12655== definitely lost: 400 bytes in 1 blocks
==12655== indirectly lost: 0 bytes in 0 blocks
==12655== possibly lost: 0 bytes in 0 blocks
==12655== still reachable: 0 bytes in 0 blocks
==12655== suppressed: 0 bytes in 0 blocks
==12655==
==12655== For lists of detected and suppressed errors, rerun with: -s
==12655== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
- testcase2 "test_deallocate" : I deallocate with size(0) less than actual size (400),valgrind or -fsanitize=address can't detect leak
当你分配错误的大小时,程序的行为是未定义的。当行为未定义时,无法保证内存会泄漏。
- testcase3 "test_deallocate2": I deallocate with size(10000) greater than actual size (400) compiler didn't warning , g++ with -fsanitize=address also can't detect this.
同上。
Valgrind 仅拦截较低级别的分配函数(malloc、new 等)。所以这完全取决于 allocate
和 deallocate
的实现。
目前 Valgrind 没有对大小删除做太多检查(或对齐新的,参见
我可能会在 2022 年为这些实现一些东西。
如果您使用 GCC libstdc++ 或 clang libc++,那么它们的大小删除不会执行任何特殊操作,它们只是调用普通删除。我还没找 deallocate
.
我检查了测试用例中使用的 libstdc++。
我看到 std::allocator::deallocate 的当前大小参数未使用。它调用删除,与new/delete运算符操作相同,它不再需要大小。
00096 void
00097 deallocate(pointer __p, size_type)
00098 { ::operator delete(__p); }
https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00958_source.html