如何在C语言中检查未初始化的指针

3
我的计算机科学教授给了我们这个任务。基本上,我们有两个未初始化的全局指针*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,我们只需要检查是否存在这样奇怪的东西,就可以知道子程序是否被调用过。这引出了另一个问题:一个不返回任何内容的子程序是否可以进行一些更改,并且即使在子程序终止后这些更改仍然保留下来?我在使用C和Xcode时尝试过,但问题要么是我没有访问所选择的随机位置的权限,要么是我不知道应该选择哪个位置不会影响程序并且不会被其他意外操作改变。


2
如果您的指针是全局的并且没有显式初始化,即使在C89中,它们也保证被零初始化。 - jamesdlin
3个回答

7
全局变量(和静态变量)如果没有显式初始化,则保证算术类型为0,指针类型为null指针。自C89以来就一直如此。
引用: C89 §3.5.7 Initialization 如果具有静态存储期的对象没有明确初始化,则会隐式初始化,就好像将每个具有算术类型的成员分配为0,并将每个具有指针类型的成员分配为null指针常量。如果具有自动存储期的对象没有明确初始化,则其值是不确定的。

2
替换
char *min_ptr, *max_ptr;

By

char *min_ptr = 0, *max_ptr = 0;

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


1
不必要,全局变量保证是空指针。 - Yu Hao
1
@Espresso 是的,如果它们具有静态存储期,那么全局变量就是如此。 - jamesdlin
不总是保证的。 - Espresso
1
@Espresso 嗯?我们在具体讨论全局变量。这种行为是有保证的。 - jamesdlin
谢谢您的评论,但我们不能修改全局变量部分。否则,这将会很容易。 - Haoyu

1
你可以使用静态变量来实现这个。
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;
    }
    // ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接