在switch语句中初始化时未定义的变量?

时间:2013-11-25 20:06:24

标签: c++ switch-statement

这个问题本身就是一个明显的答案。无论如何,这是我的代码片段......

    switch(cSet)...

    case 8:{ //Special Characters
        finalSet = special;
        char* charSet = new char[special.size() + 1];
        charSet[special.size()] = 0; //Append null terminator
        memcpy(charSet, special.c_str(), special.size());
        break;
    }

    case 9:{ //Alphnumeric and Special character
        finalSet = all;
        char* charSet = new char[all.size() + 1];
        charSet[all.size()] = 0; //Append null terminator
        memcpy(charSet, all.c_str(), all.size());
        break;
    }
    ...

请注意,finalSet的类型为std::string。我需要将其保存为字符数组。在此声明之后,我在switch语句之外调用charSet

    for(int i = 0; charSet; i++)
         printf("%s", charSet[i]);

现在,很明显switch语句是有条件的,因此可能并不总是声明变量。因此,Visual Studio 2012会抛出错误“charSet未定义”。但是,我的switch语句的结构方式总是会定义charSet,或者程序将在default情况下退出。

为解决此问题,我尝试在switch语句的范围之外声明charSet。但是,当我这样做时,由于某种原因,编译器会抛出读访问错误。

我很好奇如何解决这个问题。

赞赏任何有建设性的意见。

在switch语句之外声明时出现错误代码:

`Unhandled exception at 0x0F6616B3 (msvcr110d.dll) in cuda_comb.exe: 0xC0000005: Access violation reading location 0x00000061.`

4 个答案:

答案 0 :(得分:5)

  1. 必须charSet之外声明switch。当变量在switch / case中声明时,即使声明变量的情况被执行,它也会在开关结束时用完范围。
  2. for(int i = 0; charSet; i++)循环只要charSet不为0,每次都会增加i。因为你没有在for里面改变charSet,所以它总是不会为0,所以最终charSet[i]超出界限并给你读取访问错误。更改它以使其循环直到i大于缓冲区的长度,或charSet[i] == '0'(终止为空)。例如:

    for(int i = 0; charSet[i]; i++) 
        printf("%c", charSet[i]);
    
  3. 在您打印%s而不是printf时,还要将%c中的char更改为char *。虽然,无论如何,当你打印一个以null结尾的字符串时,你可以完全避免for循环:

    printf("%s", charSet);
    

答案 1 :(得分:2)

当你拿出来的时候,你试过(在转换之前):

char* charSet = 0;

然后在所有switch语句中删除char *,所以

char* charSet = new char[all.size() + 1];

变为:

charSet = new char[all.size() + 1];

然后你的代码甚至可以检查(切换后):

if (!charSet)
{
  // handle odd case
}

答案 2 :(得分:2)

您在每个案例块上定义charSet,尽管您在堆上为此数组分配了内存,但在这些块之外,charSet引用未定义,因为构建器正在显示。

请注意,通过执行此操作,如果您未使用charSet外部切换块,则不会收到任何错误,但会泄漏内存。

我的意思是:

switch(cSet)...

case 8:{ //Special Characters
    finalSet = special;
    char* charSet = new char[special.size() + 1]; // <-- charSet definition
    charSet[special.size()] = 0; //Append null terminator
    memcpy(charSet, special.c_str(), special.size());
    break;
} // <-- charSet reference lost, Memory leak

case 9:{ //Alphnumeric and Special character
    finalSet = all;
    char* charSet = new char[all.size() + 1]; // charSet definition
    charSet[all.size()] = 0; //Append null terminator
    memcpy(charSet, all.c_str(), all.size());
    break;
} // <-- charSet reference lost, Memory leak

} // End of switch

    for(int i = 0; charSet; i++)
     printf("%s", charSet[i]); // <-- Error charSet is not defined

正确的解决方法是在switch语句之外声明charSet,这样你就不会丢失引用:

char* charSet = NULL;
switch(cSet)...

case 8:{ //Special Characters
    finalSet = special;
    charSet = new char[special.size() + 1];
    charSet[special.size()] = 0; //Append null terminator
    memcpy(charSet, special.c_str(), special.size());
    break;
}
...
}

if(charSet)
   printf("%s", charSet);

请注意,当您使用“%s”打印数组时,可以直接使用charSet

答案 3 :(得分:0)

根据我的理解,您的代码如下所示:

 switch(cSet){    
        case 8:{ //Special Characters           
           char* charSet  = new char[special.size() + 1];
           //code
           break;
          }
         case 9:{ //Special Characters           
           char* charSet = new char[all.size() + 1];
           //code
           break;
           }
        //other cases
     }

   for(int i = 0; charSet; i++)
         printf("%s", charSet[i]);

在这种情况下,即使你为每种情况定义了字符集,你也可以将字符集的范围限制在每​​个已定义的情况下 - 你已经想出并将指针声明移到开关之外 - 如:

char* charSet;
switch(cSet){    
       //code
}

您获得的错误基本上表示您正在读取无效的内存位置。如果不将指针分配给动态分配的内存位置,则会发生这种情况。即使你似乎为switch语句的所有情况都为charSet分配内存,也不要忘记你也有一个默认情况。

希望它有所帮助。

相关问题