是否可以在C ++中获取进程的内存中第一个字符串的地址?

问题描述

是否可以在C ++中获取进程的内存中的第一个字符串的地址? 就像我不必遍历整个过程来查找字符串一样,但是我可以从第一个字符串的地址开始进行迭代?我正在谈论查找任何类型的变量中的第一个,而不仅仅是字符串,尽管我以它为例。 让我用代码举例:

for (int i = 1; i < 10000000; i++)
{
    std::string buf;
    ReadProcessMemory(hproc,(LPCVOID)i,&buf,sizeof(std::string),NULL);
    std::cout << buf << std::endl;
}

这是否有必要?我不能以第一个字符串的地址开头还是以其他方式更快地这样做吗?

解决方法

Std字符串使用与使用操作符new分配的所有其他对象相同的堆来分配其内部存储。无法区分各种内容。

也就是说,从纯粹的专业知识出发,可以使用自定义分配器声明您自己的basic_string实现,在这里您可以观察内存分配和释放。

std :: basic字符串的完整模板定义为:

template<
    class CharT,class Traits = std::char_traits<CharT>,class Allocator = std::allocator<CharT>
> class basic_string;

并且std :: string实际上是std::basic_string<char>,具体取决于Traits和Allocator的默认值。

在哪里可以提供您自己的Allocator实现,例如,它可以记录程序执行的分配和取消分配,或者将分配顺序存储在一些连续的存储中。您只会跟踪您明确声明自己的方式的字符串。

请注意,在使用不同分配器的标准容器之间禁用了移动语义,并且在许多情况下,调用以字符串为参数或以字符串作为参数的std库方法将调用自定义字符串和标准分配版本之间的副本,因此该视图可能仍然不是一个真正的人。

据我了解,当前std :: string的实现只是将字符内容存储在分配的存储中,但是可以在分配的空间中存储其他信息以帮助管理字符串的增长。

请注意,字符串的容量和当前长度存储在也指向此缓冲区的std :: string对象中,因此很难推断出有关已分配缓冲区内容的有用信息。如果将其用作合法字符串,则c ++标准说它是零终止的。因此建议将其视为C char *字符串。

许多实现都通过将非常小的字符串内联存储在std :: string对象中而没有动态分配来优化它们。他们依靠一些任意规则来了解当前的布局(nullptr,动态布局或嵌入式),例如“知道” 64位整数的容量永远不能大于56位值,因此“最高字节”始终动态字符串为零;但是实际上是一个内联字符串的1byte size(),且具有一个恒定的最大大小:然后,其余字节可用于内联内容,也许最多23个字符!

但是其他方案也是可能的。例如,旧的Microsoft字符串(不是std :: string)用于在开始时将所有长度和容量信息存储在所指向的对象中,而字符串对象是指向缓冲区下一个文本部分的简单指针。这在printf()中使用非常方便!其他c ++ 11之前的std :: string系统尝试共享字符串和存储的引用计数,但是c ++ 11的“生存期”规则实际上使这变得站不住脚。