我是一名 .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
之后:
您的代码以两种不同的方式表现出未定义的行为。
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]);
}