有没有更好的方法从 C 中的函数内修改数组?

Is there a better way of modifying arrays from within a function in C?

我正在尝试创建格式化字符串,但是我不知道为什么我无法打印我在 function.Also 中修改过的全局数组,st运行ge 行为是我无法访问只有一个特定的全局数组 (rand_session_key) 其他全局数组的其余部分表现正常(除了它们的大小不同外,正在对它们进行类似的操作)并且我可以正确访问它们的值。此代码在 esp32(DOIT Dev Kit V1)(带有 Arduino-Core)上 运行,当我在我的计算机上 运行 此程序(修改一些功能等)时,结果是我所期望的,我认为我重叠了内存中的字符或以错误的方式访问它,但如果是这种情况,我就不会在我的计算机上产生预期的输出。

我试图修改我的程序并使其更加冗长。我也 运行 相同的代码(经过一些明显的修改使其在我的计算机上 运行 ),结果如预期的那样好。

char persistent_peripheral_id[] = "FRUCTOSE96";
char rand_session_iden[7] = {'[=10=]'};
char rand_session_key[17] = {'[=10=]'};
char rand_session_channel[3] = {'[=10=]'};

char *generate_random_session_identifier(char *rand_session_iden_local)
{
    srand(time(NULL));
    int counter = 0;
    for (counter = 0; counter < 6; counter++)
        *(rand_session_iden_local + counter) = (random(10) % ('~' - ' ')) + 'k';
    rand_session_iden_local[counter] = '[=10=]';
    printf("Identifier : %s\n", rand_session_iden); //acessing global defintion of array everything is good until here
    return &rand_session_iden_local[0];
}

char *generate_random_session_key(char *rand_session_key_local)
{
    srand(time(NULL));
    int counter = 0;
    for (counter = 0; counter < 16; counter++)
        *(rand_session_key_local + counter) = (random(10) % ('~' - ' ')) + 'b';
    rand_session_key_local[counter] = '[=10=]';
    printf("Key : %s\n", rand_session_key);//acessing global defintion of array everything is good until here
    return &rand_session_key_local[0];
}

char *generate_random_session_channel(char *rand_session_channel_local)
{
    srand(time(NULL));
    int channel_value = random(100);
    sprintf(rand_session_channel_local, "%03ld", channel_value);
    printf("Channel : %s\n", rand_session_channel);//acessing global defintion of array everything is good until here
    return &rand_session_channel_local[0];
}

void begin_exchange_package()
{
    //If this does not works here (observe rand_session_key) , it will not work for sprintf also ??
    printf("\n %s-%s-%s-%s \n", (char *)persistent_peripheral_id,
           generate_random_session_identifier(rand_session_iden),
           generate_random_session_key(rand_session_key),
           generate_random_session_channel(rand_session_channel));

    //Notice it prints here ????
    printf("\n %s \n",generate_random_session_key(rand_session_key));
    Serial.println("Done");


    //sprintf((char *)plain_text_package, "{\"p\":\"%s\",\"r\":\"%s\",\"k\":\"%s\",\"c\":\"%s\"}", (char *)persistent_peripheral_id,(char *)rand_session_iden, (char *)rand_session_key , (char *)rand_session_channel);

}

void setup()
{
    Serial.begin(115200);
    begin_exchange_package();
}

void loop()
{
}

输出是 果糖96-tnltkp--094 我希望所有 4 个阵列都打印在哪里?但它确实单独打印,我的阵列是否以错误的方式终止?分配 运行dom 字符的逻辑也将始终产生可打印的 ASCII 字符(我从 esp32 网站上的论坛中了解到)

此代码...

    sprintf(rand_session_channel_local, "%03ld", channel_value);

... 要求 rand_session_channel_local 指向至少 四个 个字符的数组,因为 at 将打印至少三个数字加上一个字符串终止符。它指向的数组 rand_session_channel 只有三个字符长。结果行为未定义。

观察到的 UB 表现与内存中布局的全局数组一致,rand_session_key 紧跟在 rand_session_channel 之后,因此溢出后者意味着字符串终止符被写入前者的位置 0,使其成为一个空字符串。但是请注意,您不能依赖于预测 UB 的表现,通常分析它们也没有多大用处。相反,避免锻炼 UB。

不清楚您使用的 random 函数是什么,因为 C 标准库不带参数,但是如果您的参数指定 exclusive 上限那么您可以将 sprintf 格式更改为 "%02ld"。或者,将 rand_session_channel 的大小增加到至少 4.