2013-10-10 6 views
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; 
} 

ответ

1

почему статический символ из [0]; не выдает предупреждение

Это undefined behavior, чтобы указать массив нулевого размера, и компилятор не обязан производить диагностику в таких случаях. Если мы посмотрим на C99 draft standard раздела 6.7.5.2массива declarators пункт говорит (курсив мой ):

[..] Если они разграничивают выражение (которое определяет размер массива), то выражение должно иметь целочисленный тип. Если выражение является константным выражением, оно должно иметь значение больше нуля. [...]

Хотя gcc предупредит вас в этом случае, если вы используете -pedantic флаг, я получаю следующее предупреждение :

предупреждение: ISO C запрещает массив нулевого размера наружу '[-pedantic]

Если это также не определено , чтобы получить доступ к обр ay вне границ и то же самое касается здесь предупреждений.

, если мы посмотрим на определение неопределенного поведения в разделе 3.4.3 в пункте говорит (курсив мой):

Примечание Возможно неопределенное поведение в диапазоне от полностью игнорируя ситуацию с непредсказуемыми результатами, к вести себя во время трансляции или выполнения программы документированным образом, характерным для окружающей среды (с выдачей диагностического сообщения или без него), до прекращения перевода или выполнения (с выдачей диагностического сообщения).

Использование переменной static для выхода представляет собой проблематичный дизайн, это означает, что каждый вызывающий объект к этому методу будет иметь один и тот же выход. Лучшим выбором было бы использовать malloc для динамического выделения памяти, что означает, что вам нужно запомнить память после того, как вы закончите.

+0

Нулевой размер массива не является причиной того, что это не вызывает предупреждения. http://ideone.com/ejmIdU –

+1

Ok malloc - бог, у меня есть ответ на первый вопрос, спасибо. К второму вопросу я не должен использовать ноль, так что будет правильным значением? В этом случае я намерен использовать статический символ для моего понимания. – pipe3r

+0

@HansZ Есть несколько вопросов, на данный момент я думаю, что я обратился ко всем из них. Если у вас есть более конкретные вопросы, дайте мне знать. –

3

Нет C компилятора, который я знаю, не дает предупреждению о недоступном массиве имеет доступ. Вы сами по себе, чтобы убедиться, что индекс массива находится в границах.

+0

Вы правы. Пример работает без ошибок. – pipe3r

3

Я думаю, вы должны использовать динамическое выделение с таНосом:

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

И не забудьте освободить «из» после того, как вы использовали его

+1

Чтобы быть понятным, вам нужно добавить 1 к размеру, который вы выделяете, потому что строки C должны быть обнулены: http://en.wikipedia.org/wiki/Null-terminated_string –

+0

Использование malloc + 1 для \ 0 это еще один вариант, который я мог бы использовать. я хотел бы попробовать другой способ со статистической памятью, чтобы увидеть, что происходит. Это хороший совет, спасибо. – pipe3r

Смежные вопросы