2017-02-03 47 views
4

我遇到与char数组初始化的意外交互。C - 数组初始化使用strlen使数组大小错误

当初始化一个大小为strlen(char参数[])的char []时,新初始化的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; 
} 

富现在打印

Length of str: 1 
Length of testString: 1 

我有一种感觉,它是与焦炭方式[]传递到功能,或可能的strlen的一个意想不到的行为,但我真的没有理念。

任何帮助表示赞赏。

+1

嗯......你根本没有初始化你的'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的输出,但该阵列​​实际上是2个字节

另一种方式来做到这一点是:

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

日输出将是0和​​的实际长度是1