C - 使用strlen初始化数组导致数组大小错误

4

我在char数组初始化时遇到了意外的交互。

当使用strlen( char parameter[] )作为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;
}

现在foo会输出

Length of str: 1
Length of testString: 1

我有一种感觉,这可能与char[]传递到函数中的方式有关,或者可能是strlen的意外行为,但我真的不知道。

欢迎提供任何帮助。


1
嗯...你没有初始化testString数组。你指定了大小,但是数组本身没有被初始化:它包含垃圾值。尝试对未初始化的数组应用strlen会导致未定义的行为。这就是你观察到的情况。是的,未定义的行为可能会表现出不可预测的方式,甚至可能会看起来“神奇地自我修复”。 - AnT stands with Russia
http://stackoverflow.com/questions/16381307/strlen-of-a-char-array-is-greater-than-its-size-how-to-avoid - Bagus Tesa
2个回答

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

这个方法很有用,谢谢!显然我需要提高对数组行为的理解。 - 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;
}

那么输出将是0,而testString[]的实际长度为1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接