zoukankan      html  css  js  c++  java
  • Windows内存管理(3)--检查内存可用性,结构化异常处理 和 ASSERT

    1.      检查内存可用性

    在驱动程序开发中,对内存的操作要格外小心。如果某段内存是只读的,而驱动程序试图去写操作,会导致系统的崩溃。

    DDK提供了两个函数,帮助程序员在不知道某段内存是否可读写的情况下,试探这段内存的可读写性。

    VOID 
      ProbeForRead(
        IN CONST
     VOID  *
    Address,
        IN SIZE_T  
    Length,
        IN ULONG  
    Alignment
        );

    VOID 
      ProbeForWrite(
        IN CONST 
    VOID  *
    Address,
        IN SIZE_T  
    Length,
        IN ULONG  
    Alignment
        );

    这两个函数不是返回该段内存是否可读写,而是当不可读写的时候,引发一个异常。

     

     

    2.      结构化异常处理

     

    (1)   try-except块

    __try 

    {

            // guarded code

    }

    __except ( expression )

    {

            // exception handler code

    }

     

    其中expression ()

    {

        NT_STATUS status = STATUS_SUCCESS;

        status = Foo1(…);

        if(!NT_SUCCESS(status))

        {

           //回收资源;

           //return status

    }

     

        status = FooN(…);

        if(!NT_SUCCESS(status))

        {

           //()

    {

        NT_STATUS status = STATUS_SUCCESS;

        __try

    {

    status = Foo1(…);

            if(!NT_SUCCESS(status))

            {

               //return status<span courier="" new";="" mso-hansi-font-family:"courier="" new";mso-bidi-font-family:"courier="" mso-font-kerning:0pt;"="" style="font-family: 宋体; ">;

    }

     

    status = Foo2(…);

        if(!NT_SUCCESS(status))

        {

           //return status

    }

     

        status = FooN(…);

        if(!NT_SUCCESS(status))

        {

           //return status

    }

    }

    __finally

    {

        if(!NT_SUCCESS(status)

    {

            //统一回收资源

    }

    return status;

    }

    }

     

     

    3.      断言

    在驱动程序中,使用“断言”,一般是通过ASSERT宏。例如:

    NTSTATUS Foo(PCHAR* str)

    {

           ASSERT(str!=NULL);    //断言

           //对str的操作。

    }

    这段代码认为输入绝不可能是空指针,因此在函数的开头做了一个断言。一旦断言失败,会引发一个异常,并终止程序。

     

    例如:

    用C语言的知识解释如下:

    assert( <expression> ); 

    expression结果为时,会在stderr中输出这条语句所在的文件名和行号,以及这条表达式。这只在调试版本中起作用,在Release版本中不会产生任何代码。 
    通常当我们使用assert时,都在强烈说明一个含义:在这里必然如此。它通常用于一个函数的先验条件和后验条件的检查。比如我写一个C风格复制字符串的函数,并且认为调用者不应该传入NULL指针: 

    char   *   clone_string(const   char   *   source) 

        char   *   result; 
        assert(source   !=   NULL); 
        result   =   (char   *)malloc(strlen(source)   +   1); 
        if   (result   !=   NULL) 
        { 
            strcpy(result,   source); 
            assert(strcmp(result,   source)   ==   0); 
        } 
        return   result; 

    注意到我对source是否为NULL是用assert检查的,但对result是不是为NULL是用if语句判断的,这是因为在调用代码正确的情况下source必然不为NULL,如果断言失败,说明调用代码中有错误,需要修改;但result作为malloc的返回值则不一定,在malloc代码无误的情况下仍然可能返回NULL——当内存块不足时。最后又用assertstrcpy的结果进行检查,因为只要代码正确,无论什么情况strcpy应该正常完成复制,它没有malloc那种异常情况存在。

  • 相关阅读:
    无限分类 引用传值
    jQeury 自动、手动左右切换
    $_POST 为空时 真正的值
    php isset 备忘
    php empty 备忘
    无限分级函数 简单 引用绑值
    无限分级 层次输出 demo
    利用新版ShareSDK进行手动分享(自定义分享界面)
    eclipse 快捷方式大全
    ViewPager onPageChangeListener总结
  • 原文地址:https://www.cnblogs.com/vcerror/p/4289081.html
Copyright © 2011-2022 走看看