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

Undefined variable when initialized in switch statement?

本文关键字:未定义 变量 初始化 switch 语句      更新时间:2023-10-16

这个问题本身需要一个显而易见的答案。无论如何,下面是我的代码片段。。。

    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.`
  1. 您必须在switch之外声明charSet。当变量在开关/案例中声明时,即使声明变量的案例被执行,当开关结束时,它也会超出范围
  2. 只要charSet不为0,您的for(int i = 0; charSet; i++)就会循环,并且每次递增i。因为您没有在for中更改charSet,所以它将始终不为0,因此最终charSet[i]超出了界限,并给您带来读取访问错误。更改它,使其循环,直到i大于缓冲区的长度或charSet[i] == '0'(终止null)。例如:

    for(int i = 0; charSet[i]; i++) 
        printf("%c", charSet[i]);
    
  3. 在打印char而不是char *时,也要将printf中的%s更改为%c。尽管,在打印以null结尾的字符串时,您可以完全避免for循环:

    printf("%s", charSet);
    

当你取出它时,你尝试过(在切换之前):

char* charSet = 0;

然后在所有切换语句中删除char *,因此

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

变为:

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

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

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

您在每个case块上定义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

据我所知,您的代码如下所示:

 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的内存,但不要忘记您还有一个默认情况。

希望能有所帮助。