【问题标题】:How to check uninitialized pointer in C如何检查C中未初始化的指针
【发布时间】:2013-10-28 02:52:45
【问题描述】:

我的 CS 教授给我们布置了这个作业。基本上我们有这两个未初始化的全局指针*min_ptr, *max_ptr。我们正在编写这个void spray_paint( char *x, int sz, char tok, char *t ) 函数,它获取tok 的值并放入内存中从xx+sz-1 开始的某个位置。 char *t 只是用于调试目的的一些随机事物。 *min_ptr, *max_ptr 用于跟踪我们打印的内容的范围。但是,我无法初始化前两个指针。起初,我试图检查它们是否被初始化为 NULL,但我意识到它们仅在 C99 之后默认初始化为 NULL,我的教授说如果没有指定,你不能假设它们被初始化为 NULL,并且我们只能访问void spray_paint( char *x, int sz, char tok, char *t ),而不是代码中的其他任何地方。无论如何要检查两个全局指针是否已初始化?还是在第一次调用子例程时初始化它们,然后再也不这样做?

char *min_ptr, *max_ptr;
void spray_paint( char *x, int sz, char tok, char *t )
{
char *marker = x + 3;
char *painter = x;
int k;

//if (!min_ptr || !max_ptr)
if (*marker != '~')
{
    *marker = '~';
    min_ptr = x;
    max_ptr = x + sz - 1;
}

for (k = sz - 1; k >= 0; k--)
{
    *(painter+k) = tok;
    if ((unsigned long) x < (unsigned long) min_ptr)
        min_ptr = x;
    else if ((unsigned long) x > (unsigned long) max_ptr)
        max_ptr = x;
}

printf("%s\n",t);
printf("\n"); 
}

一个想法是在内存中找到一个位置,让子程序第一次在那里放一些奇怪的东西,即*marker,我们只需要检查是否有这种奇怪的东西就知道是否之前已经调用过子程序。这就引出了另一个问题,即使在子例程终止后,一个不返回任何内容的子例程是否可以进行一些保持不变的更改?我在 Xcode 上使用 C 进行了尝试,但问题是我无法访问我选择的随机位置,或者我不知道我应该在哪里选择不会影响程序并获胜的位置'不会被其他意外操作更改。

【问题讨论】:

  • 如果您的指针是全局的并且没有显式初始化,那么即使在 C89 中,它们也保证是零初始化的。

标签: c pointers


【解决方案1】:

未显式初始化的全局变量(和静态变量)保证算术类型为0,指针类型为空指针。自 C89 以来就是如此。

C89 §3.5.7 Initialization

如果一个具有静态存储持续时间的对象没有显式初始化,它会被隐式初始化,就好像每个具有算术类型的成员都被分配了 0 并且 每个具有指针类型的成员都被分配了一个空指针常量。 如果一个具有自动存储时长的对象没有被显式初始化,那么它的值是不确定的。

【讨论】:

    【解决方案2】:

    替换

    char *min_ptr, *max_ptr;
    

    char *min_ptr = 0, *max_ptr = 0;
    

    您无法验证指针是否已初始化,但可以通过测试其值是否为 NULL。

    【讨论】:

    • 没必要,全局变量保证为空指针。
    • @Espresso 是的,如果它们有静态存储持续时间,它们就是全局变量。
    • 是的,并不总是保证。
    • @Espresso 嗯?我们在这里专门讨论全局变量。行为保证的。
    • 感谢您的评论,但我们无法修改全局变量部分。否则,这很容易。
    【解决方案3】:

    您可以为此使用静态变量。

    void spray_paint( char *x, int sz, char tok, char *t )
    {
        static int initialized = 0;
    
        if (!initialized)
        {
            initialized = 1;
            min_ptr = x;
            max_ptr = x;
        }
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-11
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多