2017-02-03 3 views
4

Я испытываю неожиданное взаимодействие с инициализацией массива char.C - Инициализация массива с использованием массива strlen неправильного размера

При инициализации char [] с размером strlen (параметр char []), новый инициализированный символ [] слишком велик. Я не уверен, что вызывает это.

int main(void) 
{ 
    char myString[] = { " " }; 
    foo(myString); 
}  


int foo(char str[]) 
{ 
    char testString[ strlen(str) ]; 
    printf("Length of testString: %lu\n", strlen(testString)); 
    return 0; 
} 

Когда я бегу Foo, выход

Length of testString: 6 

, когда я ожидал, чтобы это было 1.


Даже незнакомец когда я добавить оператор печати в Foo до инициализации testString, выход, кажется, магически фиксирует себя:

int foo(char str[]) 
{ 
    printf("Length of str: %lu\n", strlen(str)); 
    char testString[ strlen(str) ]; 
    printf("Length of testString: %lu\n", strlen(testString)); 
    return 0; 
} 

Foo печатает

Length of str: 1 
Length of testString: 1 

У меня есть ощущение, что у него есть что-то делать с тем, как полукокса [] передаются в функции, или, возможно, неожиданное поведение STRLEN, но у меня действительно нет идея.

Любая помощь приветствуется.

+1

Um ... Вы не инициализируете свой массив 'testString' вообще. Вы указали размер, но сам массив оставлен неинициализированным: он содержит мусор. Попытка применить «strlen» к неинициализированному массиву приводит к неопределенному поведению. Это то, что вы наблюдаете. И да, неопределенное поведение может и будет вести себя непредсказуемым образом и даже может показаться «волшебным образом зафиксировать себя». – AnT

+0

http://stackoverflow.com/questions/16381307/strlen-of-a-char-array-is-greater-than-its-size-how-to-avoid –

ответ

5

Массив не был инициализирован

char testString[ strlen(str) ]; 

Таким образом, применяя функцию StrLen, чтобы это приводит к неопределенному поведению.

printf("Length of testString: %lu\n", strlen(testString)); 

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

char testString[ strlen(str) ]; 
testString[0] = '\0'; 

кажется, что вы имеете в виду это sizeof оператор.Если это так, вы можете написать

printf("Length of testString: %zu\n", sizeof(testString)); 

Вот демонстративного программу

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

void foo(const char str[]) 
{ 
    char testString[ strlen(str) ]; 
    printf("Length of testString: %zu\n", sizeof(testString)); 
} 

int main(void) 
{ 
    char myString[] = { " " }; 
    foo(myString); 

    return 0; 
} 

Его выход

Length of testString: 1 
+0

Это сделало трюк, спасибо! Мне, очевидно, нужно разобраться в моем понимании поведения массива. – JGut

0

запомнить две вещи:

  1. STRLEN() приводит к смещению к символу NUL в строке и
  2. смещения в массивы начинаются с 0, а не 1

и теперь код:

#include <string.h> // strlen(), strcpy() 
#include <stdio.h> // printf() 

int main(void) 
{ 
    char myString[] = { " " }; <<-- actual length 2 (a space + a NUL) 
    foo(myString); 
}  


int foo(char str[]) 
{ 
    char testString[ strlen(str) ]; <<-- strlen() yields 1, and testString not initialized 
    printf("Length of testString: %lu\n", strlen(testString)); <<-- strlen searchs until a NUL byte found which could be anywhere 
    return 0; 
} 

Suggested corrections: 

int foo(char str[]) 
{ 
    char testString[ strlen(str)+1 ]; 
    strcpy(testString, str); 
    printf("Length of testString: %lu\n", strlen(testString)); 
    return 0; 
} 

Примечание: Выход указанного выше/скорректированного код 1, но массив testString[] фактически 2 байта

еще один способ сделать это:

int foo(char str[]) 
{ 
    char testString[ strlen(str) ] = {'\0'}; 
    printf("Length of testString: %lu\n", strlen(testString)); 
    return 0; 
} 

й en выход будет 0, а фактическая длина testString[] равна 1

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