关于游戏安全的一个问题不理解??



```c++
今天遇到了一个关于游戏安全问题,有个老师说
可以通过把数据打乱的方式保证它不会被索到
比如int gold=1000
当我们用CE搜1000时,可能就会找到gold的真实地址,
但是如果我们把gold在内存中的存储方式打乱,比如
gold四个字节,每个字节拆分开,然后把每个字节打乱并将每一份保存起来
当需要显示gold时,再把保存好的一份重新组合就能显示
我知识水平不够,不理解的地方是,当把它重新组合的时候,组合完毕后
不就再内存中有一个完整的gold了吗,不还是能被搜索到??


  • 你可以看下这个问题的回答https://ask.csdn.net/questions/838880
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:为什么我的交换函数不起作用?
  • 除此之外, 这篇博客: 数据结构基础知识点,看完保证期末不挂科!中的 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 一种可以实现“先进后出”的存储结构
    分类:

    1. 静态栈
    2. 动态栈(链表实现)

    栈的核心操作:

    1. 压栈(入栈)
    2. 出栈
      栈的示意图如下:
      栈示意图
      为什么不反过来?
      原因:入栈代码确实会更简单,但出栈代码会很复杂,pTop上一个节点会找不到,导致pTop无法指向上一个节点。
      实现代码如下:
    
    #include <stdio.h>
    #include <malloc.h>
    #include <stdlib.h>
    
    typedef struct Node
    {
    	int data;
    	struct Node* pNext;
    
    } NODE,*PNODE;
    
    typedef struct Stack
    {
    	PNODE pTop;
    	PNODE pBottom;
    }STACK,*PSTACK;
    
    void init(PSTACK pS);          //初始化一个栈
    void push(PSTACK pS, int val); //入栈
    bool empty(PSTACK pS);		   //判断栈是否为空
    void traverse(PSTACK pS);	   //遍历一个栈
    bool pop(PSTACK pS, int* pval);//出栈
    void clear_one(PSTACK pS);     //清空栈第一种实现
    void clear_two(PSTACK pS);     //清空栈第二种实现
    
    int main(void) 
    {
    	STACK S;
    	init(&S);
    	traverse(&S);
    	push(&S,1);
    	push(&S,2);
    	push(&S,3);
    	push(&S,4);
    	push(&S,5);
    	push(&S,6);
    	traverse(&S);
    	int i;
    	pop(&S,&i);
    	pop(&S,&i);
    	printf_s("出栈元素是%d", i);
    	pop(&S,&i);
    	pop(&S,&i);
    	traverse(&S);
    	push(&S, 1);
    	push(&S, 2);
    	push(&S, 3);
    	push(&S, 4);
    	push(&S, 5);
    	push(&S, 6);
    	traverse(&S);
    	clear_one(&S);
    	traverse(&S);
    	push(&S, 1);
    	push(&S, 2);
    	push(&S, 3);
    	push(&S, 4);
    	push(&S, 5);
    	push(&S, 6);
    	traverse(&S);
    	clear_two(&S);
    	traverse(&S);
    	return 0;
    }
    
    //初始化一个栈
    void init(PSTACK pS)
    {
    	pS->pTop = (PNODE)malloc(sizeof(NODE));
    	if (NULL== pS->pTop)
    	{
    		printf_s("动态分配内存失败");
    		exit(-1);
    	}
    	else
    	{
    		pS->pBottom = pS->pTop;
    		//将pTop指向的节点的指针域赋空(使其不链着下一个节点)
    		pS->pTop->pNext = NULL;
    	}
    
    }
    
    //入栈
    //pS:指向栈的指针
    //val:入栈元素的值
    void push(PSTACK pS, int val)
    {
    	PNODE pNew = (PNODE)malloc(sizeof(NODE));
    	if (NULL== pNew)
    	{
    		printf_s("动态分配内存失败");
    		exit(-1);
    	}
    	pNew->data = val;
    	pNew->pNext = pS->pTop;
    	pS->pTop = pNew;
    	return;
    }
    
    //判断栈是否为空
    bool empty(PSTACK pS)
    {
    	if (pS->pTop == pS->pBottom)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    	
    }
    
    //遍历一个栈
    void traverse(PSTACK pS)
    {
    	if (empty(pS))
    	{
    		printf_s("栈为空!");
    		return;
    	}
    	PNODE p = pS->pTop;
    	while (p!=pS->pBottom)
    	{
    		printf_s("%d \n", p->data);
    		p = p->pNext;
    	}
    }
    
    //出栈
    //pS:指向栈的指针
    //pval:出栈元素的指针
    bool pop(PSTACK pS, int* pval)
    {
    	if (empty(pS))
    	{
    		return false;
    	}
    	else
    	{
    		PNODE p = pS->pTop;
    		*pval = p->data;
    		pS->pTop = pS->pTop->pNext;
    		free(p);
    		p = NULL;
    		return true;
    	}
    }
    
    //清空栈第一种实现
    //r为一个指针,永远指向p下一个节点
    void clear_one(PSTACK pS)
    {
    	if (empty(pS))
    	{
    		printf_s("栈为空!");
    		return;
    	}
    	PNODE p = pS->pTop;
    	PNODE r = NULL;
    	while (p!=pS->pBottom)
    	{
    		r = p->pNext;
    		free(p);
    		p = r;
    	}
    	pS->pTop = pS->pBottom;
    	return;
    }
    
    //清空栈第二种实现,比较好理解
    //r用于保存要释放内存的节点
    void clear_two(PSTACK pS)
    {
    	if (empty(pS))
    	{
    		printf_s("栈为空!");
    		return;
    	}
    	PNODE p = pS->pTop;
    	PNODE r = NULL;
    	while (p != pS->pBottom)
    	{
    		r = p;
    		p = p->pNext;
    		free(r);
    		r = NULL;
    	}
    	pS->pTop = pS->pBottom;
    	return;
    }
    

    栈的应用:
    1.函数调用
    2.中断
    3.表达式求值
    4.内存分配
    5.缓冲处理
    6.走迷宫问题

  • 您还可以看一下 刘伶华老师的软件测试经典面试题剖析课程中的 你还有什么问题想问?小节, 巩固相关知识点