[英]Iterating through const char* array
I have an really simple example of array of const char's and one function supposed to print them out (iterate through the chosen one). 我有一个非常简单的const char数组的例子和一个应该打印出来的函数(遍历所选的一个)。 Contrary all my expectations, it's iterating through all of them and not only the one that was passed as argument. 与我的所有期望相反,它正在迭代所有这些,而不仅仅是作为参数传递的那个。
#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;
}
The result i would expect is that the function printFruit with oranges given as argument will print ORANGE and RED ORANGE, meanwhile i get printed ALL of the fruits defined (from other arrays), like this: 我期望的结果是作为参数给出橙色函数printFruit将打印ORANGE和RED ORANGE,同时我打印所有定义的水果(来自其他数组),如下所示:
---------------------
ORANGE
---------------------
RED ORANGE
---------------------
APPLE
---------------------
LEMON
Sorry for my ignorance but why is this happening ? 对不起我的无知,但为什么会这样?
Edit: I followed this question: defining and iterating through array of strings in c that is similar to mine. 编辑:我遵循了这个问题: 定义和迭代c中与我类似的字符串数组 。
You are having UB here. 你在这里有UB。 Your condition 你的病情
while (fruit[i] != '\0')
will never be met because there are no elements that are equal to \\0
. 永远不会满足,因为没有等于\\0
元素。
All the arrays are placed exactly one after another in the memory. 所有数组都在内存中一个接一个地放置。 Your i
keeps increasing forever. 你的i
永远在增加。 On i = 1
you are on the first string in oranges
. 在i = 1
你在oranges
的第一个字符串。 On i = 2
you are on the second element. 在i = 2
你在第二个元素上。
After that, i
becomes 3. Since right after oranges
, in your mamory lies the apples
array, your pointer starts pointing to it and the app prints APPLE
. 在那之后, i
变成了3.因为在oranges
之后,在你的妈妈的谎言apples
阵列,你的指针开始指向它,应用程序打印APPLE
。 On i = 4
the pointer is on the lemons
array and the app prints LEMONS
. 在i = 4
,指针位于lemons
数组上,应用程序打印LEMONS
。 After that you effectively go out of your own memory which for me results in a crash. 之后,你有效地走出了自己的记忆,这对我来说会导致崩溃。
To fix that you need to explicitly add an empty element into each of the arrays, eg 要解决此问题,您需要在每个数组中显式添加一个空元素,例如
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0
};
You are checking that fruit[i] != '\\0'
. 你正在检查fruit[i] != '\\0'
。 That is wrong because fruit[i]
is a char *
, not a char. 这是错误的,因为fruit[i]
是char *
,而不是char。 Furthermore, your vectors aren't terminated. 此外,您的向量不会终止。 You probably wanted to check whether fruit[i] != 0
, or *fruit[i] != '\\0'
. 您可能想检查fruit[i] != 0
,或*fruit[i] != '\\0'
。 In the first case, you need to terminate the vectors like this: 在第一种情况下,您需要终止这样的向量:
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
0 // or NULL
};
In the second: 在第二:
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
""
};
IMHO, you'd be better off knowing exactly how many elements that you're dealing with. 恕我直言,你最好知道你正在处理多少元素。 The bad news is that a simple array of character pointers won't tell you (it's not a std::vector
) so you won't be able to discover it in your printFruit
function. 坏消息是一个简单的字符指针数组不会告诉你(它不是std::vector
)所以你将无法在printFruit
函数中发现它。
The good news, however, is that it is available at compile time so you don't have to worry about the overhead of finding it out. 然而,好消息是它可以在编译时使用,因此您不必担心找到它的开销。 The following shows what I mean: 以下显示了我的意思:
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;
}
Since you're using C++ though, I'd strongly recommend that you use one of the standard collection types such as vector
as they're much safer when it comes to bounds checking, memory allocation etc. 既然您正在使用C ++,我强烈建议您使用其中一种标准集合类型,例如vector
因为它们在边界检查,内存分配等方面更安全。
const char* oranges[] = {
"ORANGE",
"RED ORANGE"
};
const char* apples[] = {
"APPLE"
};
const char* lemons[] = {
"LEMON"
};
in memory will looks somthing like 在记忆中会看起来像
"ORANGE""RED ORANGE""APPLE""LEMON" “ORANGE”“RED ORANGE”“APPLE”“LEMON”
while (fruit[i] != '\0'){
std::cout << "---------------------\n";
std::cout << fruit[i] << "\n";
i++;
}
will end when you reach the end of "big array" which is "LEMON" 当你到达“LEMON”的“大阵列”结束时将结束
to make your code working you need memory to looks like "ORANGE""RED ORANGE"0"APPLE"0"LEMON"0 so 为了使你的代码工作你需要内存看起来像“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
};
const char* oranges[] = {
"ORANGE",
"RED ORANGE",
"\0"
};
Your arrays are located in memory one after another so it continues printing others because the while
condition is false
您的阵列一个接一个地位于内存中,因此它会继续打印其他数据,因为while
条件为false
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.