2维wchar_t字符串数组的简单示例

时间:2012-10-23 14:22:40

标签: c++ c

有人可以解释为什么下一个代码输出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;
     }

3 个答案:

答案 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::vectorstd::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,所以这可能不是一个大问题。