Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在内存中搜索字符串会导致崩溃 我对C++不太好,但是我在内存中遇到了一个字符串扫描问题。_C++_Memory - Fatal编程技术网

在内存中搜索字符串会导致崩溃 我对C++不太好,但是我在内存中遇到了一个字符串扫描问题。

在内存中搜索字符串会导致崩溃 我对C++不太好,但是我在内存中遇到了一个字符串扫描问题。,c++,memory,C++,Memory,下面是我的代码的一个小示例: for (unsigned int i = 0x400000; i < 0xFFFFFFFFFF; i++) { string s = (char *) i; if (s[0] == 'H') { if (s == "Hello") { cout << "Found at address: " << i << endl; } } } for(无

下面是我的代码的一个小示例:

for (unsigned int i = 0x400000; i < 0xFFFFFFFFFF; i++) {
    string s = (char *) i;
    if (s[0] == 'H') {
        if (s == "Hello") {
            cout << "Found at address: " << i << endl;
        }
    }
}
for(无符号整数i=0x400000;i<0xffffffff;i++){
字符串s=(char*)i;
如果(s[0]=='H'){
如果(s==“你好”){

延迟任意指针值(地址)是一种未定义的行为,因平台和操作系统而异


崩溃是许多未定义的行为之一。

尽管标签中没有提到它,但基于对
ReadProcessMemory
的提及,我假设您希望在Windows中使用它

要在Windows中实现这一点,您几乎需要使用
VirtualQuery
来确定地址空间的哪些部分是可用的(在64位系统上尤其重要,在64位系统中,有效地址比32位系统上少得多)

使用VirtualQuery查找可搜索块的代码可能如下所示:

#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>

template <class InIter1, class InIter2, class OutIter>
void find_all(InIter1 buf_begin, InIter1 buf_end, InIter2 pat_begin, InIter2 pat_end, OutIter output) { 
    for (auto pos = buf_begin;
        buf_end != (pos = std::search(pos, buf_end, pat_begin, pat_end));
        ++pos)
    {
        *output++ = (void *)pos;
    }
}

template <class outIter>
void find_locs(std::string const &pat, outIter output) {

    unsigned char *p;
    MEMORY_BASIC_INFORMATION info;

    for ( p = nullptr;
        VirtualQuery(p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        if (info.State == MEM_COMMIT && 
           (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE)) 
        {
            find_all(p, p + info.RegionSize, pat.begin(), pat.end(), output);
        }
    }
}

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <pattern>", argv[0]);
        return 1;
    }

    find_locs(argv[1], std::ostream_iterator<void *>(std::cout, "\n"));
}
#包括
#包括
#包括
#包括
#包括
#包括
模板
void find_all(InIter1 buf_begin、InIter1 buf_end、InIter2 pat_begin、InIter2 pat_end、OutIter输出){
对于(自动位置=buf_开始;
buf_end!=(pos=std::search(pos,buf_end,pat_begin,pat_end));
++pos)
{
*输出++=(void*)位置;
}
}
模板
无效查找位置(标准::字符串常量和pat,输出){
无符号字符*p;
内存\基本信息\信息;
对于(p=nullptr;
虚拟查询(p,&info,sizeof(info))==sizeof(info);
p+=信息区域大小)
{
如果(info.State==MEM_COMMIT&&
(info.Type==MEM_-MAPPED | | info.Type==MEM_-PRIVATE))
{
查找所有(p,p+info.RegionSize,pat.begin(),pat.end(),output);
}
}
}
int main(int argc,字符**argv){
如果(argc!=2){
fprintf(stderr,“用法:%s”,argv[0]);
返回1;
}
查找位置(argv[1],std::ostream\u迭代器(std::cout,“\n”);
}
预计会出现一些“虚假”匹配。特别是,即使您搜索的字符串没有出现在进程内存空间的其他任何位置,也会有一个副本作为
argv
的一部分,并且(至少)对于传递给
find_locs
的临时
std::string
,还有一个匹配项,因此对于可能传递的任何字符串,至少要有两个匹配项


您可能还需要通读文档中的
内存\u基本信息
。我已经选择了(我非常确定)可以安全读取的块子集(即提交的、映射的或私有的)但是,根据您要查找的内容,您可能希望将其更改为仅通过程序文本而不是文本和数据进行搜索。

This
string s=(char*)i;
将导致未定义的行为。
i
不是以null结尾的字符串。是的,我意识到了这一点,但问题是如何修复它?或者用任何其他方法防止它崩溃?
VirtualQuery
可以告诉您哪些地址空间区域由实际内存支持。或者,您可以使用
IsBadRe进行探测adPtr
。或者,您可以继续并访问
\uuuuu try/\uuuuu except
块下的内存,并适当地处理SEH异常。
字符串
是不必要的,可能会尝试分配任意数量的内存-
char*s=(char*)i;如果(*s='H')…
。否,则
(char i)i
自身强制转换不会导致崩溃。尝试从结果指针构造
std::string
会导致崩溃(因为构造函数尝试读取指向的内存)。删除
std::string
,使用普通
char*
指针和C样式比较(请参见例如
memcmp
)我已经说过,在最初的问题中,我只是想知道是否有可能防止崩溃,或者至少有另一种方法。这取决于平台和操作系统,没有通用的方法。需要传递的参数是什么?我看到有一种“模式”有吗?@John:就目前的情况而言,您可以像这样运行它:
搜索“我的字符串”
。尽管有“模式”,它实际上只搜索文字匹配。