【发布时间】:2015-03-13 22:34:00
【问题描述】:
考虑以下代码:
std::vector<std::string> foo{{"blee"}, {"bleck"}, {"blah0000000000000000000000000000000000000000000000000000000000000000000000000000000000"}};
std::string *temp = foo.data();
char*** bar = reinterpret_cast<char***>(&temp);
for (size_t i = 0; i < foo.size(); ++i){
std::cout << (*bar)[i] << std::endl;
}
显然这是粗略的代码,但它恰好可以工作。
我想知道它为什么有效?有一些我不知道的奇怪的 C++ 规则吗?还是只是糟糕的代码和未定义的行为?
我将其中一个字符串设置得很大,以防进行一些小字符串优化。
【问题讨论】:
-
字符串可能将指向其缓冲区的指针存储为第一个结构成员,因此其地址与字符串对象本身的地址相同。我不会说“它有效”;而是假装工作。
-
@TheParamagneticCroissant 是的,我也打赌,但我认为依靠创建应该始终有效的代码并不是一个好主意...
-
我认为这与 std::vector 行为有关。它保证有连续的内存,甚至复制和移动它的数据来完成这个保证。如果将固定内存大小的静态 std::strings 放入其中,它们将被放置在连续的内存块中,您可以做这样的技巧:)。要检查它,你可以 push_back 向量中的另一个字符串,看看你以前的数据指针是否仍然有效。
标签: c++