由batman所发代码引申出的变量最大长度问题,以下代码由batman、随风、我共同讨论测试得出,结果也只是提出一个猜想,望大家讨论补充!
1、首先给出随风的一个测试代码 | @echo off | | setlocal enabledelayedexpansion | | for /l %%a in (1 1 10000) do ( | | set m=a!m!||(echo %%a&pause) | | ) | | pauseCOPY |
结果为8190,这时可能大家会认为最大长度应该是8190。
2、现在做一个小小的改变,把以上代码中的set m=a!m!||(echo %%a&pause)改为set var=a!var!||(echo %%a&pause)。再次运行,按理说结果应该没影响,可是出乎我们的意料,结果为8188。这是为何?参照batcher给出的资料,可以推出变量名和等号都占字节。
3、现在再做出一个改变,把set m=a!m!||(echo %%a&pause),改为set “m=a!m!“||(echo %%a&pause),再次运行,结果是8188。又困惑了,我们一般来看set "str1=str2"和set str1=str2所达到的效果是一样的。再根据资料The maximum individual environment variable size is 8192bytes。我想着要从环境变量的内存空间分配角度来思考了。环境变量分配的最大空间为8192字节。其中包括变量名、等号、引号(如果有的话)、以及变量所包含的字符。
4、为了更加清晰,对刚才代码增加一些。如下: | @echo off | | setlocal enabledelayedexpansion | | for /l %%a in (1 1 10000) do ( | | set a=!a!0 | | ) | | if "!a:~8181,1!"=="" echo 8181 | | if "!a:~8182,1!"=="" echo 8182 | | if "!a:~8183,1!"=="" echo 8183 | | if "!a:~8184,1!"=="" echo 8184 | | if "!a:~8185,1!"=="" echo 8185 | | if "!a:~8186,1!"=="" echo 8186 | | if "!a:~8187,1!"=="" echo 8187 | | if "!a:~8188,1!"=="" echo 8188 | | if "!a:~8189,1!"=="" echo 8189 | | if "!a:~8190,1!"=="" echo 8190 | | if "!a:~8191,1!"=="" echo 8191 | | if "!a:~8192,1!"=="" echo 8192 | | if "!a:~8193,1!"=="" echo 8193 | | pauseCOPY |
执行后显示为8189,按照刚才的分析,共占有的字节数:8189+1('a')+1('=')=8191,不是8192。这又是为何?再看下面?
5、batman提供的代码: | @echo off | | setlocal enabledelayedexpansion | | for /l %%a in (1 1 10000) do ( | | set a=!a!0 | | ) | | set a=!a:0=1! | | echo !a! | | pauseCOPY |
上面代码可以正常运行,可是把上面的代码中set a=!a:0=1!改为:set a=%a:0=1%则提示输入过长。这说明开启变量延迟内存中的分配发生变化,到底是什么变化?期待有人来提供一些资料。
6、第四步分析的还差一个字节,我猜想是不是内存自动占用一个固定的标记字节,来标志是否启动了变量延迟以及其他的一些标志。此也期待有心人来完善。
7、这就是我们的初步分析,可以知道的是单个环境变量的最大的内存分配为8192字节(有资料为证),对于这么多字节的如何分配还有待继续探索。欢迎大家一起来讨论!
[ 本帖最后由 lhjoanna 于 2009-2-21 22:44 编辑 ] |