游戏辅助原理——基址与动态地址

    在前面一节课我们已经实现了游戏的阳光值修改,并且也写出了程序,现在我们重新打开游戏,再启动我们写的程序,并进行修改:

游戏辅助原理——基址与动态地址

我们发现,修改失败!这是为什么呢?难道我们的阳光的内存地址发生了变化?

我们打开工具,再次进行寻找:

游戏辅助原理——基址与动态地址

我们重新寻找后,发现现在的阳光内存地址为:171A2578,而我们之前所找到的地址是:20194DC8。看来我们的阳光地址已经发生了变化,那这到底是为什么呢?

    这里,一些C/C++比较好的同学和有过游戏开发经验可能已经推断出来了,其实这就是我们C/C++语言通常用到的一个做法:动态内存分配。

    我们把游戏的阳光值当作C语言的一个变量,可以简单的理解为:int n_sunshine;那么这个游戏的经过编译后,这个变量的地址在以下几种情况下是会发生变化的:

    1.作为局部变量的时候。

    2.n_sunshine在某个结构体(或者类)里面,而这个结构体或者类的内存是动态分配的。

当其作为全局变量时,程序编译的时候已经分配好了全局数据区的地址,所以里面的数据地址是不会变得。简单点来说,动态分配就是在运行时分配的,具体怎么分配,由操作系统决定,而全局变量的地址,是编译时就确定的,所以是不会变的。


那么,阳光值到底是怎样的一个情况呢。对于游戏的开发,一般都是面向对象的,所以我们可以推测阳光值这个变量应该在某个类的示例指针里面,类的示例指针在运行时进行动态内存的分配,为其分配内存。为了阐述这个过程,我用简单的代码的表示:


  1. class Game_Info{
  2. int n_Sunshine;//阳光值
  3. ....//其它成员
  4. }
  5. Game_Info *Game_Info_PvZ;
  6. int main()
  7. {
  8. Game_Info_PvZ = new Game_Info;
  9. return 0;
  10. }

在代码中,我定义了一个类Game_Info,并定义了这个类的示例指针Game_Info_PvZ。这个指针变量的地址,是存在全局数据区的,地址并不会随运行改变。在主函数中,我们为这个实例指针动态分配了内存,这句代码是在运行中执行的,所以所分配的内存的地址是不定的,所以阳光值的地址也是不定的。

到这里,我们就可以解释为什么我们每次找的阳光地址都发生了改变了 。我们这里提出两个概念:基址和动态地址。对于这里的基址,我们可以理解成在全局数据区的数据的地址,它的地址是不会发生改变的。对于动态地址,则是我们程序在运行时动态分配的地址,它的地址是不会发生改变的。


				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
										if(!window.csdn.anonymousUserLimit.judgment()){
											window.csdn.anonymousUserLimit.Jumplogin();
											return false;
										}else if(!currentUserName){
											window.csdn.anonymousUserLimit.updata();
										}
									}
									
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>

优秀博主:https://blog.csdn.net/xiaokangdream/article/category/7463395