我有一个非常简单的const char数组的例子和一个应该打印出来的函数(遍历所选的一个)。与我的所有期望相反,它正在迭代所有这些,而不仅仅是作为参数传递的那个。
#include <iostream>
const char* oranges[] = {
"ORANGE",
"RED ORANGE"
};
const char* apples[] = {
"APPLE"
};
const char* lemons[] = {
"LEMON"
};
void printFruit(const char** fruit){
int i =0;
while (fruit[i] != '\0'){
std::cout << "---------------------\n";
std::cout << fruit[i] << "\n";
i++;
}
}
int main (int argc, const char * argv[])
{
printFruit(oranges);
return 0;
}
我期望的结果是带有橙色的函数printFruit作为参数将打印ORANGE和RED ORANGE,同时我打印所有定义的水果(来自其他数组),如下所示:
---------------------
ORANGE
---------------------
RED ORANGE
---------------------
APPLE
---------------------
LEMON
对不起我的无知,但为什么会这样?
编辑:我关注了这个问题:defining and iterating through array of strings in c与我的相似。
答案 0 :(得分:6)
你在这里有UB。你的病情
while (fruit[i] != '\0')
永远不会满足因为没有等于\0
的元素。
所有数组都在内存中一个接一个地放置。你的i
永远在增加。在i = 1
上,您在oranges
的第一个字符串中。在i = 2
,你是第二个元素。
之后,i
变为3.自oranges
之后,在你的妈妈的谎言apples
数组中,你的指针开始指向它,应用程序打印APPLE
。在i = 4
上,指针位于lemons
数组上,应用程序将打印LEMONS
。在那之后,你有效地走出了自己的记忆,这对我来说会导致崩溃。
要解决此问题,您需要在每个数组中显式添加一个空元素,例如
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0
};
答案 1 :(得分:5)
您正在检查fruit[i] != '\0'
。这是错误的,因为fruit[i]
是char *
,而不是char。此外,您的向量不会终止。您可能想检查fruit[i] != 0
或*fruit[i] != '\0'
。在第一种情况下,您需要终止这样的向量:
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0 // or NULL
};
在第二个:
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
""
};
答案 2 :(得分:2)
std::vector
)所以你将无法在printFruit
函数中发现它。
然而,好消息是它在编译时可用,因此您不必担心找到它的开销。以下是我的意思:
void printFruit(const char** fruit, int fruitSize){
int i =0;
while (i < fruitSize){
std::cout << "---------------------\n";
std::cout << fruit[i] << "\n";
i++;
}
}
int main (int argc, const char * argv[])
{
// The second parameter can be worked out by the compiler.
printFruit(oranges, sizeof(oranges)/sizeof(const char*) );
return 0;
}
由于您使用的是C ++,我强烈建议您使用其中一种标准集合类型,例如vector
,因为它们在边界检查,内存分配等方面更安全。 / p>
答案 3 :(得分:1)
const char* oranges[] = {
"ORANGE",
"RED ORANGE"
};
const char* apples[] = {
"APPLE"
};
const char* lemons[] = {
"LEMON"
};
内存中的看起来像
“ORANGE”“RED ORANGE”“APPLE”“LEMON”
while (fruit[i] != '\0'){
std::cout << "---------------------\n";
std::cout << fruit[i] << "\n";
i++;
}
当你到达“LEMON”的“大阵”结束时,将结束
要使代码正常工作,您需要内存 “ORANGE”“RED ORANGE”0“APPLE”0“LEMON”0所以
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0
};
const char* apples[] = {
"APPLE",
0
};
const char* lemons[] = {
"LEMON"
,0
};
答案 4 :(得分:0)
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
"\0"
};
您的数组一个接一个地位于内存中,因此{01}} while
条件为false