2017-02-03 8 views
4

予期せぬ文字配列の初期化とのやりとりがあります。C - strlenを使って配列を初期化する配列が間違っています

strlen(charパラメータ[])のサイズでchar []を初期化すると、新たに初期化されたchar []が大きすぎます。私はこれを引き起こしているのか分かりません。私がfooにprint文を追加したとき

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


ことさえ知らない人期待していています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が、今、私はそれがchar []は機能、または多分strlen関数の予期しない動作に渡されますが、私は本当にありません持っている方法とは何かを持っていることを感じている

Length of str: 1 
Length of testString: 1 

を印刷しますアイディア。

何か助けていただければ幸いです。

+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

は、アレイは、したがって、それは未定義の動作結果をSTRLEN関数を適用

char testString[ strlen(str) ]; 

初期化されませんでした。

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. アレイにの
  3. オフセットはない1

、0で始まり、現在コード:

#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の出力が、アレイ​​は実際に2バイトであります

それを行うための別の方法は次のとおりです。

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

番目出力は0で、実際の長さは​​です。

関連する問題