返回 C++ 中的字符串数组、长度和损坏

问题描述 投票:0回答:1

我是一名 .NET 人员,正在深入研究 C++/微控制器领域。

以下是我正在尝试做的事情的模型。我有一个传入值的方法,并且根据该值我想返回一个不同的硬编码字符串数组。

当我逐步执行此操作时,

main()
中的函数似乎可以工作,并且看起来我正在函数中返回正确的类型。我可以设置一个断点并查看
files[0]
是预期的字符串,
files[1]
是预期的字符串,等等。我可以单步执行循环并设置
files[i]
的监视,然后我会看到适当的字符串。那里一切都很好。

那么两个问题:如何获取数组中有多少个元素?看了一百万个帖子,看来我做不到,对吧?我是否只需要一些在循环时需要检查的结束字符串(例如空字符串)?

其次,您会注意到我已将

printf()
注释掉了。当我启用该功能后,在单步执行
printf()
后,它会更改字符串的内容,但我不明白为什么要这样做。查看逐步执行之前/之后的图像以及手表的结果。我认为这可能是因为字符串没有以
\0
隐式终止,但这没有效果。

#include <cstdlib>
#include <cstdio>

const char** GetSoundCategory(int category)
{
    const char* FILES1[3] = {
        "/myfile1.mp3",
        "/this_is_my_file.mp3",
        "/myfile9.mp3"
    };

    const char* FILES2[2] = {
        "/I love S.E.mp3",
         "/please_help_me.mp3"
    };   

    const char** ptr = nullptr;

    switch (category)
    {
        case 1:
            ptr = FILES1;
            break;
        case 2:
            ptr = FILES2;
            break;
    }
    return ptr;
}

int main()
{
    const char** files = GetSoundCategory(2);
    constexpr int number_of_files = 3;

    for (int i = 0; i < number_of_files; i++)
    {
        //  printf("%s\n", files[i]);
    }
}

之前

printf

printf
之后:

c++ visual-c++
1个回答
0
投票

您的代码以两种不同的方式表现出未定义的行为

GetSoundCategory()
返回一个指向局部变量的指针,该变量在
GetSoundCategory()
退出时被释放,因此在调用者有机会使用它之前,返回的指针就指向无效内存。

由于你的数组不会改变,你可以将它们移动到全局内存或静态内存中,以便它们在

GetSoundCategory()
退出后保持活动状态,例如:

static const char* FILES1[3] = {
    "/myfile1.mp3",
    "/this_is_my_file.mp3",
    "/myfile9.mp3"
};

static const char* FILES2[2] = {
    "/I love S.E.mp3",
    "/please_help_me.mp3"
};   

const char** GetSoundCategory(int category)
{
    ...
}

或者:

const char** GetSoundCategory(int category)
{
    static const char* FILES1[3] = {
        "/myfile1.mp3",
        "/this_is_my_file.mp3",
        "/myfile9.mp3"
    };

    static const char* FILES2[2] = {
        "/I love S.E.mp3",
         "/please_help_me.mp3"
    };   

    ...
}

除此之外,根据

GetSoundCategory()
的编码方式,
main()
无法知道返回的数组中实际有多少个字符串。所以,当
category == 2
时,它的循环就出界了。

要解决这个问题,您必须返回数组长度以及数组指针。您可以使用输出参数来做到这一点,例如:

const char** GetSoundCategory(int category, int *length)
{
    ...

    *length = ...;
    return ...;
}

...

int number_of_files;
const char** files = GetSoundCategory(2, &number_of_files);

或者,通过返回一个简单的

struct
(或
std::pair
)来保存数组指针和数组长度:

struct filesArray {
    const char** files;
    int number_of_files;
};

filesArray GetSoundCategory(int category)
{
    ...

    filesArray fa;
    fa.files = ...;
    fa.number_of_files = ...;

    return fa;
}

...

filesArray fa = GetSoundCategory(2);

for (int i = 0; i < fa.number_of_files; i++)
{
    printf("%s\n", fa.files[i]);
}
© www.soinside.com 2019 - 2024. All rights reserved.