[expr.new]
C++的5.3.4 2月草案给出了一个例子:
new(2,f) T[5]
导致打电话operator new[](sizeof(T)*5+y,2,f)
.这里,x和y是非负的未指定值,表示数组分配开销; new-expression的结果将从返回的值中抵消此数量
operator new[]
.这种开销可以应用于所有数组新表达式,包括那些引用库函数operator new[](std::size_t, void*)
和其他放置分配函数的表达式.开销的数量可能因新的一次调用而异.- 末端的例子 ]
现在来看以下示例代码:
void* buffer = malloc(sizeof(std::string) * 10);
std::string* p = ::new (buffer) std::string[10];
Run Code Online (Sandbox Code Playgroud)
根据上面的引用,第二行将new (buffer) std::string[10]
在内部调用operator new[](sizeof(std::string) * 10 + y, buffer)
(在构造单个std::string
对象之前).问题是如果y > 0
,预分配的缓冲区太小了!
那么我如何知道在使用数组放置时预先分配多少内存?
void* buffer = malloc(sizeof(std::string) * 10 + how_much_additional_space);
std::string* p = ::new (buffer) std::string[10];
Run Code Online (Sandbox Code Playgroud)
或者标准某处是否保证y == 0
在这种情况下?报价再次说:
这种开销可以应用于所有数组新表达式,包括那些引用库函数
operator …
在这里讨论之后,如果你想要一个安全的类来存储内存中的敏感信息(例如密码),你必须:
所以这听起来不错,我创建了一个测试类来查看它是否有效.所以我做了一个简单的测试用例,我继续添加单词"LOL"和"WUT",然后在这个安全缓冲类中加上一个数字大约一千次,破坏该对象,然后再做一些导致核心转储的事情.
由于该类应该在破坏之前安全地清除内存,因此我不应该在coredump上找到"LOLWUT".但是,我设法找到它们,并想知道我的实现是否只是错误.但是,我尝试使用CryptoPP库的SecByteBlock做同样的事情:
#include <cryptopp/osrng.h>
#include <cryptopp/dh.h>
#include <cryptopp/sha.h>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <cryptopp/filters.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(){
{
CryptoPP::SecByteBlock moo;
int i;
for(i = 0; i < 234; i++){
moo += (CryptoPP::SecByteBlock((byte*)"LOL", 3));
moo += (CryptoPP::SecByteBlock((byte*)"WUT", 3));
char buffer[33];
sprintf(buffer, "%d", i);
string thenumber (buffer);
moo += (CryptoPP::SecByteBlock((byte*)thenumber.c_str(), thenumber.size()));
}
moo.CleanNew(0);
}
sleep(1);
*((int*)NULL) = 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后编译使用:
g++ clearer.cpp -lcryptopp …
Run Code Online (Sandbox Code Playgroud)