我不明白为什么这个字符串串联有效

时间:2019-09-30 01:19:51

标签: c

我想进一步了解C字符串及其在幕后的工作方式。我声明了3个字符串,分别为53、11和33个字节长(包括每个字符串末尾的\0)。然后,我将它们连接到一个新字符串to_be_used,并将其手动设置为 33个字节长(我通过反复试验发现了该值,直到该值较小时结果字符串变得奇怪为止)然后33)。请输入以下代码:

void generate_random_password(int password_lenght, int has_special_characters)
{
    const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const char digits[] = "0123456789";
    const char special_characters[] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

    char random_password[password_lenght + 1];

    if(has_special_characters == 1)
    {
        char to_be_used[33];

        strcat(to_be_used, letters);
        strcat(to_be_used, digits);
        strcat(to_be_used, special_characters);

        printf("%s\n", to_be_used);
        printf("%d\n%d\n%d\n%d\n", sizeof(letters), sizeof(digits), sizeof(special_characters), sizeof(to_be_used));
    }
}

此代码的输出是:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
53
11
33
33

此函数调用的每个参数都将第一个参数设置为17,将最后一个参数设置为1。

来自strcat()调用的结果字符串正是我所期望的。我的问题是:即使3个字符串的大小之和为94(不包括每个字符串结尾的\ 0)并且我将结果字符串设置为33,为什么仍会编译此代码?

我希望我解释对了。

请,如果有人知道编写此代码的更好方法(当然是这样),请回答我该代码如何更好,例如使用指向char,malloc()的指针或其他方法。谢谢!

PS:此功能尚未完成。 PS2:我是C编程的初学者。

2 个答案:

答案 0 :(得分:0)

超出范围写入数组是未定义的行为,这意味着任何事情都可能发生。这就像玩俄罗斯轮盘赌。在这个特定程序中,您碰巧遇到了麻烦,并使其覆盖了一些相对不重要的内存(可能是button *{class: sales_button(sales) } type="button" ),因此它似乎可以正常工作。下次您可能不会那么幸运。

答案 1 :(得分:0)

分配足够的内存是您的责任。

当您违约时,编译器没有义务抓住您。 strcat的约定是目标数组足够大以容纳结果。如果不遵守,则行为是不确定的。有关更多信息,请参见undefined behaviour

顺便说一句,您不能strcat未初始化的字符串。

    char to_be_used[33];
    strcat(to_be_used, letters); // <- uninitialised, another instance of undefined behaviour