将 += 与字符串一起使用时出现奇怪的段错误

发布于 2024-07-19 14:01:27 字数 762 浏览 1 评论 0原文

对于 C++ 来说,肯定有一些明显的我没有意识到的地方。

load(string & filename){

 string command;
 char delimiter = '/';
 size_t delimiterPos = filename.rfind(delimiter);
 string directory = string(filename.c_str(),delimiterPos);
 command = "import path ";

  //want to add directory to end of command
  string temp = command + "hello!"; // This works
  command.append(directory); //This works!
  command += directory;  //This seg faults!
  ...
}

在 GDB 中,当我在函数开头“打印”文件名时,我得到: (常量字符串&)@0x9505f08:{静态npos = 4294967295, _M_dataplus = {>; = {<__gnu_cxx::new_allocator>; = {}, }, _M_p = 0x950a8e4 "../config/pythonFile.py"}}

到底是什么,文件名格式如何错误,导致 .append() 有效而 += 无效?! C++ 中的重载函数 += 有什么奇怪的吗?

g++ 版本 3.4.6

There must be something obvious I don't realize about C++ with this one.

load(string & filename){

 string command;
 char delimiter = '/';
 size_t delimiterPos = filename.rfind(delimiter);
 string directory = string(filename.c_str(),delimiterPos);
 command = "import path ";

  //want to add directory to end of command
  string temp = command + "hello!"; // This works
  command.append(directory); //This works!
  command += directory;  //This seg faults!
  ...
}

in GDB when I "print" filename at the beginning of the function I get:
(const string &) @0x9505f08: {static npos = 4294967295,
_M_dataplus = {> = {<__gnu_cxx::new_allocator> = {}, }, _M_p = 0x950a8e4 "../config/pythonFile.py"}}

What the heck, how is filename formatted incorrectly, such that .append() works and += doesn't?! Something strange in the overloaded function += in C++?

g++ version 3.4.6

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏の忆 2024-07-26 14:01:27

也许这与你在这里构建“目录”的方式有关

 size_t delimiterPos = filename.rfind(delimiter);
 string directory = string(filename.c_str(),delimiterPos);

rfind 是否以某种方式失败? 如果 rfind 失败,它将返回指定的 std::npos 在这里。 我不确定如果将 npos 传递到字符串构造函数中会发生什么行为。 它可能依赖于平台。

这并不能回答为什么“append”会起作用而“+=”会崩溃。 您还可能会遇到某种堆损坏(可能是由传递到上面构造函数的 npos 和 C 字符串引起的),并且可能在调用 += 时需要分配新内存。 无论出于何种原因追加可能都不需要分配新的内存。

无论如何,增加对非营利组织的检查是明智的。

Maybe it has to do with how you are constructing "directory" here

 size_t delimiterPos = filename.rfind(delimiter);
 string directory = string(filename.c_str(),delimiterPos);

Is rfind somehow failing? If rfind failed, it would return std::npos as specified here. I'm not sure what the behavior would be if you passed npos into the string constructor. It may be platform dependent.

This doesn't answer why "append" would work and "+=" would crash. You may also have some kind of heap corruption (maybe caused by the npos and C string passed into the constructor above) and maybe when += is called new memory needs to be allocated. Append for whatever reason may not need to allocate new memory.

In any case, it would be wise to add a check for npos.

一江春梦 2024-07-26 14:01:27

我无法重现你的问题。 下面的文件适用于 g++:

#include <string>
#include <iostream>

using namespace std;

int main(int, char**)
{
 string filename("a/b/c/d");

 string command;
 char delimiter = '/';
 size_t delimiterPos = filename.rfind(delimiter);
 string directory = string(filename.c_str(),delimiterPos);
 command = "import path ";

  //want to add directory to end of command
  string temp = command + "hello!"; // This works
  command.append(directory); //This works!
  cout << command << endl;

  command += directory;  //This seg faults!
  cout << command << endl;

}

输出:

$ g++ -o t t.cpp
$ ./t
import path a/b/c
import path a/b/ca/b/c

I can not reproduce your problem. The file below works here with g++:

#include <string>
#include <iostream>

using namespace std;

int main(int, char**)
{
 string filename("a/b/c/d");

 string command;
 char delimiter = '/';
 size_t delimiterPos = filename.rfind(delimiter);
 string directory = string(filename.c_str(),delimiterPos);
 command = "import path ";

  //want to add directory to end of command
  string temp = command + "hello!"; // This works
  command.append(directory); //This works!
  cout << command << endl;

  command += directory;  //This seg faults!
  cout << command << endl;

}

Output:

$ g++ -o t t.cpp
$ ./t
import path a/b/c
import path a/b/ca/b/c
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文