首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >删除C中指向范围外静态数据的指针。

删除C中指向范围外静态数据的指针。
EN

Stack Overflow用户
提问于 2012-04-03 18:05:03
回答 5查看 784关注 0票数 13

免责声明:这个问题完全是学术性的。我要举的例子可能是糟糕的风格。

假设在C中,我编写了这个表单的一个子例程:

代码语言:javascript
复制
char *foo(int x)
{
    static char bar[9];

    if(x == 0)
        strcpy(bar, "zero");
    else
        strcpy(bar, "not zero"),

    return bar;
}

然后,在其他地方,我使用foo,如下所示:

代码语言:javascript
复制
printf("%i is %s\n", 5, foo(5));

我的指针和静态变量的心智模型预测,在实践中,这个printf的输出将是

5不是零

...but,这实际上是C标准所要求的,还是我在鼻腔恶魔的领地?

更糟糕的是,像这样的

代码语言:javascript
复制
strcpy(foo(5), "five");

我的心智模型说,除非它是明确非法的,否则它应该“起作用”,尽管它有点毫无意义,因为它不影响foo的输出。但是,这实际上是由标准定义的吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-04-03 18:07:59

你写的是好的,没有鼻恶魔在等着你。即使是strcpy()示例也是'OK‘,因为没有超出数组的界限。这个'OK‘是用引号表示的,因为这不是一个好主意,但正如所写的,没有超出边界的内存访问,因此没有未定义的行为。函数中的static数据贯穿于程序的整个生命周期,其中包含了写入它的最后一个值。

如果您尝试:

代码语言:javascript
复制
printf("%i is %s but %i is %s\n", 5, foo(5), 0, foo(0));

对于这两个数字中的一个,你会得到错误的答案,但没有定义哪个是错误的答案。

票数 11
EN

Stack Overflow用户

发布于 2012-04-03 18:08:25

既然你想引用标准的话:

对象的生存期是程序执行期间保证为其保留存储的部分。

一个对象,其identier被声明时没有存储类specifier ,并且具有外部或内部链接或与存储类specifier静态,则具有静态存储持续时间。它的生存期是程序的整个执行过程,其存储的值在程序启动之前只初始化一次。

票数 4
EN

Stack Overflow用户

发布于 2012-04-03 18:09:25

在任何条件下,foo()都会返回一个指向静态变量的指针,该变量的生存期是永久的(也就是说,当控制第一次传递到程序结束时,它就会存活)。这完全没问题。

您的代码的逻辑不太好;例如,函数不是可重入的,而且远离线程安全,当然,没有保护的字符串操作完全是自杀。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9998834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档