正确的静态数组大小

时间:2013-10-10 15:49:22

标签: c string memory static

我有一个有效的功能,但我想知道为什么static char out[0];在需要在范围内分配静态内存时不会产生警告?在此示例中,out的大小的正确值是什么?:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *hex(char *s)
{
    int i, l = (int)strlen(s);
    static char out[0]; // should it be 7 ?
    for(i = 0; i < l; i++) {
        s[i] -= 5;
        sprintf(&out[i*6], "0x%02x, ", (unsigned char)s[i]);
    }
    return out;
}

int main(void)
{
    char s[] = "hello";
    printf("%s", hex(s)); // 0xa8, 0xa5, 0xac, 0xac, 0xaf, 
    return 0;
}

3 个答案:

答案 0 :(得分:3)

我知道没有C编译器为越界数组访问提供警告。您可以自己确保数组索引处于边界内。

答案 1 :(得分:3)

我认为你必须使用malloc动态分配:

char *out = malloc(6 * strlen(s) + 1); // 6 = strlen("0xXX, ")

并且在使用它之后不要忘记释放“out”

答案 2 :(得分:1)

  

为什么静态char out [0];不会抛出警告

这是undefined behavior来指定零大小的数组,并且编译器没有义务在这种情况下生成诊断。如果我们查看C99 draft standard部分6.7.5.2 数组声明符 1 说(强调我的):

  

[..]如果它们分隔表达式(指定数组的大小),则   表达式应具有整数类型。 如果表达式是常量表达式,则其值应大于零。[...]

虽然gcc会在这种情况下警告您使用-pedantic标志,但我会收到以下警告:

  

警告:ISO C禁止零大小数组'out'[-pedantic]

如果它也 undefined 来访问一个超出界限的数组,这里也适用于警告。

如果我们在段落 2 中的3.4.3部分中查看未定义行为的定义(强调我的):

  

注意可能的未定义行为包括完全忽略具有不可预测结果的情况,在翻译或程序执行期间以环境特有的文档形式表现(有或没有发出诊断消息) ,终止翻译或执行(发布诊断信息)。

对输出使用static变量是一个有问题的设计,这意味着该方法的每个调用者将共享相同的输出。一个更好的选择是使用 malloc 来动态分配内存,这意味着你必须在完成后记住释放内存。