对内存字节的理解

为了加强自己的记忆,我决定用文字记录下来。

这是源代码,主要是输出环境变量,具体可以参考CreateEnvironmentBlock函数

 1 #include <Windows.h>
 2 #include <UserEnv.h>
 3 #include <assert.h>
 4 #include <stdio.h>
 5 #pragma comment(lib, "userenv.lib")
 6 #pragma warning(disable : 4996)
 7 
 8 int main()
 9 {
10     HANDLE hToken = NULL;    
11     BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken);
12     /*assert(ok);
13 
14     wchar_t* penv = NULL;
15     ok = CreateEnvironmentBlock((void**)&penv, hToken, TRUE);
16     assert(ok);
17 
18     while (*penv) {
19         printf("%lsn", penv);
20         penv += wcslen(penv) + 1;
21     }*/
22     wchar_t* wnext = NULL;
23     LPVOID pEnvironment = NULL;
24     ok = CreateEnvironmentBlock(&pEnvironment,
25         hToken,
26         FALSE);
27     if (!ok)
28     {
29         // handle error
30     }
31 
32     wchar_t* wtemp = (wchar_t*)pEnvironment;
33 
34     do
35     {
36         wnext = wtemp + wcslen(wtemp) + 1;
37         int m = wcslen(wtemp);
38         if (*(wnext+1) == L'') // Crashes here
39         {
40             break;
41         }
42         else
43         {
44             wtemp = wnext;
45             printf("%lsn", wtemp);
46         }
47     } while (1);
48 
49     return 0;
50 }

注释部分可以不用看,主要注意 if (*(wnext+1) == L'') 这行

下面两张图分别是控制台输出结果和内存字节

对内存字节的理解

 

 

 对内存字节的理解

 

 

 从第二张图可以看到控制台打印到windir=C:WINDOWS之后,下面就会打印空行,再然后就会进入break,这是为什么呢?

我们已知宽字节占两个字节,所以一次会跳过2个点,包括r. s. 等等,我们在执行wnext = wtemp + wcslen(wtemp)+1这行代码时,实际上是相当于wtemp地址往后移动 wcslen(wtemp)+1个地址位,而我们在往后移动 wcslen(wtemp)时,我们其实到达了C.:..W.I.N.D.O.W.S.的S.的位置,再+1就相当于到C.:..W.I.N.D.O.W.S...的位置,+1的原因是为了跳过的字符串结束位,到这边是将(..)这个空的赋给wnext,而在执行到下一行代码if (*(wnext+1) == L''),地址相当于又往后面移动一个宽字节,也就是C.:..W.I.N.D.O.W.S.....,然后我们判断这之后的(.),把它与L''进行比较,发现它不为0,然后代码跳到else上面。

重点来了,wtemp = wnext;这行代码其实是把C.:..W.I.N.D.O.W.S...后面的(..)这个空的内存字节赋给wtemp,打印为空,并不是C.:..W.I.N.D.O.W.S.....,因为C.:..W.I.N.D.O.W.S.....这个只是后面用于比较的,然后到wnext = wtemp + wcslen(wtemp) + 1这行代码,之前wtemp为空,所以wcslen(wtemp) = 0, 再+1,往后面移一个地址,就到了C.:..W.I.N.D.O.W.S.....上的最后一个点的位置,接着执行到下一行代码if (*(wnext+1) == L''),地址上再+1,相当于跳过了(.),我们需要比较(.)后面的值,也就是(..),可以看到是空,然后与L''相同,到了break,跳出while循环,程序结束。

 

这段代码的正确输出要把if (*(wnext+1) == L'')中的+1去除,这样避免指针指向未知的内存区域。

可能写的有点乱,仅供参考吧,我也是第一次接触,很多术语都没怎么明白。

 

原文链接: https://www.cnblogs.com/strive-sun/p/11436343.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    对内存字节的理解

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405125

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月25日 下午4:54
下一篇 2023年4月25日 下午6:08

相关推荐