【问题标题】:Unhandled Exception when converting const char to char将 const char 转换为 char 时出现未处理的异常
【发布时间】:2013-08-05 09:29:38
【问题描述】:

在过去的 30 分钟里,我一直在尝试将 const char 转换为 char。 这就是我所拥有的。

 string atr; 

 getline(cin,atr); // Start off with a string because getline takes nothing else.
 const char *buffA = atr.c_str(); // Create a const char of the string converted to a const char.
 char *buff = ""; // Create a new char to hold the converted result.
 strcat(buff,buffA); // Do the conversion.
 parseargs(buff); // Pass the data on.

但是,我得到一个未处理的异常。我不知道为什么。我只是在控制台中输入了“try”作为我唯一的参数。

【问题讨论】:

  • "我一直在尝试将 const char 转换为 char" NO NO NO NO NO NO。别再想要这个了。告诉我们您正在尝试做什么,您认为可以通过将 const char 转换为 char 来完成。描述您的问题,而不仅仅是您的解决方案。
  • 但是你为什么不直接使用string呢?
  • 我建议您选择a good introductory C++ book (click on this link for a list),这样您就可以学习一些现代 C++ 技术,使您的代码更易于理解、简洁和安全。正如您在nightcracker's answer 中看到的,您的代码可以用更少的行重写并实际工作。
  • @Daaksin 但这不是你已经在做的吗? getline(cin,atr);。字符串肯定比char 数组更容易操作!

标签: c++ strcat


【解决方案1】:

尝试使用 C++ 而不是 C 习语:

std::vector<char> data(atr.begin(), atr.end());
data.push_back('\0');
parseargs(&data[0]);

【讨论】:

  • 关闭。正如所写,它可能是未定义的行为:因为parseargs 不需要长度,它几乎肯定需要一个'\0' 终止的字符串。所以你需要在通过&amp;data[0]之前推回'\0'。 (当然,如果parseargs不修改它的论点,atr.c_str()就完全解决了这个问题,很可能反正不需要副本。)
  • @JamesKanze:很好!
  • 直奔主题!感谢代码 sn-p, nightcracker!
【解决方案2】:

您的代码有两个问题。首先你 用字符串文字初始化 char*。这使用 已弃用的转换;字符串文字的类型是char const[](转换为char const*,而不是char*), 因为任何修改文字的尝试都是未定义的行为。 第二个是你的字符串文字只有一个char long, 所以即使你可以写信,除非atr 是空的,否则你就是 写入超出缓冲区的末尾。

你没有告诉我们任何关于parseargs 的事情。如果没有 修改它的参数,你可以传递它atr.c_str(),然后 完成它。 (如果它是一个忽略 const 的遗留函数, 你可能不得不在这里使用const_cast。)如果它确实修改了它的 论点(比如说因为它使用strtok),那么你必须 明确地将'\0' 推到atr 的末尾,然后传递它 &amp;atr[0]。 (不是一个特别干净的解决方案,但如果你 之后不使用atr,它应该可以工作。)

【讨论】:

  • 感谢您提供这个非常有帮助的答案!
【解决方案3】:

buffbuffA 的内容都在进程的只读内存中。
你实际上需要new你的buff喜欢

char* buff = new char[32];

这提供了来自免费存储的内存,然后您可以strcat 将字符串从buffAbuff。 你应该更喜欢strncat,但要避免缓冲区溢出,delete 最终还是你的buff

【讨论】:

  • 哦!好的,非常感谢您的回答。我总是忘记在 C++ 中你必须为你的变量分配内存。好吧,无论如何,干杯!
  • 不客气,但请不要忘记区分基于堆和基于堆栈的变量(考虑数组)!!
  • @Daaksin 最重要的是,如果您只使用string 而不是首先转换为char*,那会好很多。
  • 您绝对不想在未初始化的缓冲区上使用strcat。如果您希望稍后将指针传递给函数,您不想使用strncat。如果你知道最大尺寸,你就不想用new;你应该只使用本地缓冲区。如果你不这样做,std::vector&lt;char&gt; 将在分配和释放数组方面做得更好(并将初始化它,以便strcat 不会是未定义的行为,尽管为什么strcat,而不是strcpy 节拍我)。
【解决方案4】:

这个

char *buff = ""; // Create a new char to hold the converted result.

创建一个char *,它指向(可能是只读的)大约 1 字节范围的内存。这个:

 strcat(buff,buffA); // Do the conversion.

尝试用任意字符串覆盖(可能是只读的)大约 1 个字节的内存。

这很可能会立即崩溃。如果内存是只读的,它会立即崩溃。如果内存不是只读的,它会踩到随机数据,导致非常不确定的行为。

你到底为什么要这样做? parseArgs 真的需要一个可修改的字符串吗?它是 解析 参数,它不应该需要更改它们。如果确实有必要,请使用std::vector&lt;char&gt; 并传递第一个元素的地址,并希望它所做的只是戳数组的内容,而不是(比如说)跑到最后。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 2012-01-16
    • 1970-01-01
    相关资源
    最近更新 更多