1

我有一个可以工作的函数,但我想知道为什么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;
}
4

3 回答 3

3

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

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

使用后别忘了释放“out”

于 2013-10-10T15:54:08.970 回答
3

据我所知,没有任何 C 编译器会针对越界数组访问发出警告。您需要自己确保数组索引在界限内。

于 2013-10-10T15:50:41.380 回答
1

为什么静态字符输出[0];不抛出警告

这是指定零大小数组的未定义行为,编译器没有义务在这种情况下产生诊断。如果我们查看C99 草案标准部分6.7.5.2 Array declarators1段说(强调我的):

[..]如果他们界定了一个表达式(它指定了一个数组的大小),那么该表达式应该是一个整数类型。如果表达式是常量表达式,则它的值应大于零。[...]

尽管gcc在这种情况下如果您使用该-pedantic标志会警告您,但我收到以下警告:

警告:ISO C 禁止零大小数组“输出”[-pedantic]

如果它也未定义访问数组越界,这同样适用于警告。

3.4.3如果我们看一下第2段中未定义行为的定义说(强调我的):

注意 可能的未定义行为范围从完全忽略具有不可预测结果的情况,到在翻译或程序执行期间以环境特征的记录方式表现(有或没有发出诊断消息),到终止翻译或执行(使用发出诊断消息)。

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

于 2013-10-10T16:00:55.340 回答