【发布时间】:2022-01-03 06:55:31
【问题描述】:
我正在使用 C++ 进行试验,发现 const char* 和 const char[] 在下面的代码中表现得非常不同。如果我没有很好地表达这个问题,真的很抱歉,因为我不清楚代码中发生了什么。
#include <iostream>
#include <vector>
// This version uses <const char[3]> for <myStr>.
// It does not work as expected.
struct StrStruct
{
const char myStr[3];
};
// This program extracts all the string elements in <strStructList> and copy them to <strListCopy>
int main()
{
StrStruct strStruct1{"ab"};
StrStruct strStruct2{"de"};
StrStruct strStruct3{"ga"};
std::vector<StrStruct> strStructList{strStruct1, strStruct2, strStruct3};
std::vector<const char*> strListCopy{};
for (StrStruct strStructEle : strStructList)
{
strListCopy.push_back(strStructEle.myStr);
std::cout << "Memory address for the string got pushed back in is "
<< &strStructEle.myStr << std::endl;
std::cout << "Memory address for the first element of the string got pushed back in is "
<< (void *) &strStructEle.myStr[0] << "\n" <<std::endl;
}
std::cout << "Show content of <strListCopy>:" << std::endl;
for (const char*& strEle : strListCopy)
{
std::cout << strEle << std::endl;
}
}
以下是它的输出:
Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]
Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]
Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]
Show content of <strListCopy>:
ga
ga
ga
但是,如果我只是简单地更改 StrStruct 的实现
来自:
// This version uses <const char[3]> for <myStr>.
// It does not work as expected.
struct StrStruct
{
const char myStr[3];
};
到
// This version uses <const char*> for <myStr>.
// It works as expected.
struct StrStruct
{
const char* myStr;
};
程序的输出变成这样:
Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#1]
Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#2]
Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#3]
Show content of <strListCopy>:
ab
de
ga
让我感到困惑的是:
-
为什么在第一个版本中所有字符串都具有相同的值?我尝试在 for each 循环中使用
const strStruct&而不是strStruct来解决问题,但我不明白如何。 -
为什么
const char*和const char[]的行为如此不同?我认为它们大致相同,原因如下:
const char myChars[] = "abcde";
const char* myCharsCopy = myChars;
std::cout << myChars << " vs " << myCharsCopy << std::endl;
它打印出abcde vs abcde,你可以直接将const char[]的值赋值给const char*,没有任何错误。
- 为什么将
const char[]更改为const char*可以解决问题?
【问题讨论】:
-
for (StrStruct strStructEle : strStructList)正在制作结构的临时副本。您正在存储指向这些副本的指针,看起来因为它们在循环结束时超出范围,程序会一遍又一遍地使用相同的位置,因此所有指针都指向同一个位置。使用for (StrStruct & strStructEle : strStructList)获取对vector中原件的引用,而不是它们的副本.. -
复制
struct { char x[8]; }时复制字符串,复制struct { char *x; }时复制字符串地址。