C 如何清理由“创建”创建的已分配结构;“出去”;指针参数?

C 如何清理由“创建”创建的已分配结构;“出去”;指针参数?,c,pointers,memory-address,pass-by-pointer,C,Pointers,Memory Address,Pass By Pointer,我有一个结构变量,其传递方式如下: //function definition void function1(const Node* aVAR1) { Node* value=NULL; ..... } int main() { Node* aVAR=NULL; aVAR=x.value; function1(aVAR); } 在这里,当我在gdb中运行它,并进入function1(),我看到变

我有一个结构变量,其传递方式如下:

  //function definition
   void function1(const Node* aVAR1)
    {
        Node* value=NULL;
        .....
   }
   int main()
   {
    Node* aVAR=NULL;
    aVAR=x.value;

    function1(aVAR);
   }
在这里,当我在gdb中运行它,并进入
function1()
,我看到变量
aVAR
创建了一个临时内存地址

GDB:

比如说,

  • 最初,aVAR的地址是
    0x654321
  • 稍后一段时间,直到未执行
    function1()
    中的第一条指令,
    aVAR1
    保存在一些临时地址中,如
    0x7ffffffffbcdf
  • 执行
    节点后*value=NULL
    function1()
    中的第一条指令,
    aVar1
    的地址也是
    0x654321
  • 但此临时(
    0x7ffffffffebcdf
    )地址未清理:即使在函数退出后,
    0x7ffffffffebcdf
    也未清除
  • 我希望在函数退出后清除
    0x7ffffffffebcdf
    ,但该
    0x7ffffffffebcdf
    地址没有我可以访问此内存的指针。在GCC中链接时是否有任何选项可以防止这种情况


    如果我为aVAR添加malloc并在以后使用memset和free清除它,问题会得到解决,但在逻辑上,当我看到时,我丢失了对malloc()分配的内存块的引用,并且我将无法释放()分配的内存(导致内存泄漏)

    在您介绍的内容中,有两个变量称为
    aVAR
    。第一个是
    main
    中的本地变量,第二个是
    function1
    的参数。两者都在自动存储中(或者您称之为“临时”存储),因此当包含它们的函数退出时,它们将不再存在。不需要做什么特别的事情来释放他们

    只需要释放指向的结构(假设它是
    malloc
    ),并且只需要执行一次,不管在它的生命周期中有多少个指向它的指针


    简言之,您只需为每个
    malloc
    /
    calloc
    提供一个
    免费
    。(请记住,
    strdup
    将调用
    malloc
    ,而将
    NULL
    传递给
    realloc
    实际上是一个
    malloc

    在您介绍的内容中,有两个变量称为
    aVAR
    。第一个是
    main
    中的本地变量,第二个是
    function1
    的参数。两者都在自动存储中(或者您称之为“临时”存储),因此当包含它们的函数退出时,它们将不再存在。不需要做什么特别的事情来释放他们

    只需要释放指向的结构(假设它是
    malloc
    ),并且只需要执行一次,不管在它的生命周期中有多少个指向它的指针

    简言之,您只需为每个
    malloc
    /
    calloc
    提供一个
    免费
    。(请记住,
    strdup
    将调用
    malloc
    ,而将
    NULL
    传递给
    realloc
    实际上是一个
    malloc

    我希望在函数退出后清除0x7FFFFFFFFBCDF

    我的想象力有限,但我能想象你想要这一点的原因之一是:

  • 你认为这仍然在使用中;它不是,它超出了范围,而且无法实现
  • 如果因为您将其地址存储在某个地方而恰好可以访问它,那么您就犯了一个错误,再多的归零都无法解决
  • 您有一个安全问题,您希望确保临时内存被清除
  • 因此,考虑到[3],有两种选择;在main返回之前将代码更改为零;或者将main()更改为mymain():

    这是有效的,因为堆栈地址将在两个函数调用之间覆盖,所以您的0x7f FEbCDF将在数据[]的中间着陆。执行定义行为的唱诗班现在应该热身了。 但实际上,你最好是:

    int mymain() {
        Node* aVAR=NULL;
        aVAR=x.value;
    
        function1(aVAR);
        aVAR = 0;
        dummyfunction(&aVAR);
        return aVAR == 0;
    }
    

    注意,通过将Avar的地址提供给DimMyType,可以预先编译编译器删除它可能认为无用的功能。然而,这种行为很难预测,因为它将您的程序源绑定到您可以使用的任何编译器的任何版本;不太可能

    如果volatile的定义有任何严格性,那么它在这里会很有用,但它没有

    更好的做法是使用malloc()获取变量,然后受一个约定的约束,即这是内存[而局部变量只能是寄存器],并且可以在释放它之前清除它。对于编译器来说,优化磨砂将是不可接受的行为的外部影响。它仍然可能会将数据留在一些寄存器中,这可能会泄漏出去

    这一切都说了,;如果攻击者真的想要揭露程序中明文的秘密,您可能无法阻止他们。他们可以在调试器或虚拟机监控程序下启动您的程序,并随意检查数据

    在一些现代处理器中有这样的概念,cpu可以构造一种飞地,在那里秘密可以被安全地解开;但也有很多缺陷。有更多信息

    我希望在函数退出后清除0x7FFFFFFFFBCDF

    我的想象力有限,但我能想象你想要这一点的原因之一是:

  • 你认为这仍然在使用中;它不是,它超出了范围,而且无法实现
  • 如果因为您将其地址存储在某个地方而恰好可以访问它,那么您就犯了一个错误,再多的归零都无法解决
  • 您有一个安全问题,您希望确保临时内存被清除
  • 因此,考虑到[3],有两种选择;在main返回之前将代码更改为零;或者将main()更改为mymain():

    这是因为堆栈地址将覆盖在两个函数调用之间,所以您的0x7f febcdf
    int mymain() {
        Node* aVAR=NULL;
        aVAR=x.value;
    
        function1(aVAR);
        return something;
    }
    void clearstack() {
         int data[1000];
         int fd;
         if ((fd = open("/dev/zero", O_RDONLY)) != -1) {
              read(fd, data, sizeof data);
              close(fd);
         }
    }
    int main() {
        int r = mymain();
        clearstack();
        return r;
    }
    
    int mymain() {
        Node* aVAR=NULL;
        aVAR=x.value;
    
        function1(aVAR);
        aVAR = 0;
        dummyfunction(&aVAR);
        return aVAR == 0;
    }