StackString的Chromium堆栈容器无法工作(至少在Visual C ++中)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了StackString的Chromium堆栈容器无法工作(至少在Visual C ++中)相关的知识,希望对你有一定的参考价值。
症状
我正在调查使用铬stack_container
专门设置StackString
。我用以下方法制作了一个测试程序:
#include <chromium/base/stack_container.h>
int main() {
StackString<300> s;
return 0;
}
这应该在堆栈上创建空间,字符串将保留此空间。
我很惊讶地发现,当我在allocate
中向StackAllocator
添加一些断点时,堆栈缓冲区永远不会返回给任何人。即,通用分配器始终被调用:
pointer allocate(size_type n, void* hint = 0) {
if (source_ != NULL && !source_->used_stack_buffer_
&& n <= stack_capacity) {
source_->used_stack_buffer_ = true; // source_ is always NULL
return source_->stack_buffer(); // and so this is never returned.
} else {
return std::allocator<T>::allocate(n, hint); // This is always called.
}
}
问题
经过进一步调查,我发现这是因为当创建std::basic_string
类型时(作为StackString
构造的一部分),VisualC ++实现将分配器存储到某些对中。然后当需要使用它时,它将其复制到代理中:
void _Alloc_proxy()
{ // construct proxy
typename _Alty::template rebind<_Container_proxy>::other
_Alproxy(_Getal()); // Copies the allocator!
_Myproxy() = _Unfancy(_Alproxy.allocate(1)); // NOTE this for a later point.
...
StackAllocator
的拷贝构造函数将拷贝堆栈指针设置为NULL。因此StackString
永远不会工作。
此外,如果StackString
didnt有这个问题,它立即分配1的空间,这意味着在你添加任何东西之后,它会迅速增长并且无论如何都会遇到同样的问题。
问题
- 这是一个错误,如果是这样的话,VisualC ++还是铬?
- 如果没有出现第一个症状,那么第二个项目不会成为大多数编译器的问题吗?
似乎StackString已从Chromium项目中移除:https://bugs.chromium.org/p/chromium/issues/detail?id=709273
但这不是一个错误,而是对一个小字符串进行某种优化。
当在“Debug”中编译时,Visual Studio 2015/2017将在堆中分配一个16字节的std :: _ Container_proxy,即使对于空字符串也是如此。在“Release”中,我们不会将堆内存用于StackString。
我用这段代码测试了它:
#include <iostream>
#include <new>
#include "stack_container.h"
std::size_t memory = 0;
std::size_t alloc = 0;
void* operator new(std::size_t s) throw(std::bad_alloc) {
// Put breakpoint here
memory += s;
++alloc;
return malloc(s);
}
void operator delete(void* p) throw() {
--alloc;
free(p);
}
void PrintMem_Info()
{
std::cout << "memory = " << memory << '
';
std::cout << "alloc = " << alloc << '
';
}
int main()
{
StackString<256> str;
PrintMem_Info();
str->append("Hello World!");
PrintMem_Info();
str[0] = '1';
str[1] = '2';
}
我的解决方案是:
pointer allocate(size_type n, void* hint = 0) {
#if defined(_MSC_VER)
if (n > stack_capacity)
{
n = stack_capacity;
}
#endif // if defined(_MSC_VER)
if (source_ != nullptr && !source_->used_stack_buffer_
&& n <= stack_capacity) {
source_->used_stack_buffer_ = true;
return source_->stack_buffer();
}
else {
return std::allocator<T>::allocate(n, hint);
}
}
以上是关于StackString的Chromium堆栈容器无法工作(至少在Visual C ++中)的主要内容,如果未能解决你的问题,请参考以下文章