有人可以解释为什么下一个代码输出26 timez'Z'的范围从'A'到'Z',我怎样才能正确输出这个数组。看代码:
wchar_t *allDrvs[26];
int count = 0;
for (int n=0; n<26; n++)
{
wchar_t t[] = {L'A' + n, '\0'};
allDrvs[n] = t;
count++;
}
int j;
for(j = 0; j < count; j++)
{
std::wcout << allDrvs[j] << std::endl;
}
答案 0 :(得分:5)
问题(至少一个)是:
{
wchar_t t[] = {L'A' + n, '\0'};
allDrvs[n] = t; //allDrvs points to t
count++;
} //t is deallocated here
//allDrvs[n] is a dangling pointer
所以,简短回答 - 行std::wcout << allDrvs[j]
上的未定义行为。
要获得正确的输出 - 还有一个糟糕的丑陋版本,涉及数组之间的动态分配和复制。
然后是使用std::vector<std::wstring> >
的正确版本。
答案 1 :(得分:0)
你的t[]
在堆栈中;它只存在于循环的一次迭代中,下一次迭代似乎是重用该空间 - 而不是需要的行为,但这似乎是根据您的结果发生的事情。如果在第一个循环完成后用调试器检查allDrvs[]
,您可能会看到所有指针都指向同一个内存位置。
您可以通过多种方式解决此问题。您可以在堆上为每个循环迭代分配一个新的t
(并在之后删除它们)。您可以wchar_t allDrvs[26][2];
代替wchar_t *allDrvs[26]
,并在每次迭代时复制t
的内容。您可以在第一个循环中立即显示t
,而不是稍后再进行。您可以使用std::vector
和std::wstring
为您管理事物,而不是使用数组和指针。
答案 2 :(得分:0)
您的代码有未定义的行为。您的t
具有自动存储持续时间,因此一旦退出上部循环,它就不再存在。您的allDrvs
包含指向在第二个循环中使用它们时已被破坏的对象的26个指针。
碰巧看起来(在您正在运行它的情况下,使用您正在使用的编译器等),正在发生的事情是它正在为t
重新使用相同的存储空间循环的迭代,当你在第二个循环中使用allDrvs
时,该存储没有被覆盖,所以你有26个指向相同数据的指针。
既然你正在使用C ++,我建议使用std::wstring
而不是std::vector
代替 - 例如,这个一般顺序的东西:
std::vector<std::wstring> allDrvs;
for (char i=L'A'; i<L'Z'; i++)
allDrvs.push_back(std::wstring(i));
从技术上讲,这不是完全可移植的 - 它取决于'A' .. 'Z'
是连续的,对于所有字符集都不是这样,IBM的EBCDIC是明显的例外。即使在这种情况下,它也会生成所有正确的输出,但它还会包含一些您不想要的其他项目。
尽管如此,原始版本依赖于'A'..'Z'
是连续的,并且代码看起来似乎也适用于Windows,所以这可能不是一个大问题。