我即将调试其他人的代码,我偶然发现了一种处理全局数组的“方式”,我认为这种方式非常糟糕,但是第一次使用它的人会发誓。 我需要找到反对它的论据。 这是简化的代码(这不是原始代码,只是抽象版本)
所以我的问题:你会带来哪些参数(或者可能是某些代码会导致这种方法失败)?
int test(int i, int v, int type, int** t)
{
static int *teeest;
int result = 0;
switch(type)
{
case (1):
{
int testarr[i];
teeest = testarr;
}
break;
case (2):
result = teeest[i];
break;
case (3):
teeest[i] = v;
break;
}
if (t != NULL)
{
*t = teeest;
}
return result;
}
int main()
{
int *te = (int*)1;
test(5, 0, 1, &te);
printf("%p\n", te);
int i=0;
for(;i<5;i++)
{
test(i, i, 3, NULL);
printf("Value: %d\n", test(i,0,2, NULL));
}
return 0;
}
答案 0 :(得分:3)
局部变量在它们声明的块之后死了,所以这段代码是未定义的行为。像每个访问随机地址一样,它可能有用,但它也可能不起作用。
请注意,如果您使用malloc
代替int testarr[i]
,(并担心释放前一个数组,并初始化teeest),那么它将是正确的。这段代码的问题与静态指针无关。
答案 1 :(得分:2)
这真的很糟糕。仅仅因为指针是静态的并不意味着它指向的数据将会存在。例如,当函数退出时,testarr会消失,返回的指针(如果使用)可能会导致出现龙。
答案 2 :(得分:2)
在我看来,这种风格的大挫折是你隐藏了一个事实,即你正在访问堆栈上的本地声明的数组。然后你持有一个指向你的堆栈的指针,它将通过调用持续存在,每次调用都会有不同的堆栈。
我想到的另一件事是你从开发人员那里隐藏了数据结构。索引数组是正常操作。索引指针使开发人员确认它是一个数组而不是更复杂的数据类型。这也增加了边界检查的混乱。
答案 3 :(得分:1)
另一件事是,全局变量的所有缺点都直接适用。代码不是可重入的,并且难以使线程安全(如果这是一个问题)。