【问题标题】:const char * overwritten in next iteration of while loopconst char * 在 while 循环的下一次迭代中被覆盖
【发布时间】:2014-06-21 14:00:30
【问题描述】:

首先,一切都发生在 do{}while 循环中的 if{} 语句中。我有一个包含一些 const char 指针的结构。我试图在每次迭代时将信息放入一个带有新字符串值的临时结构中,然后将此结构推入所述结构的向量中,以便当函数退出时,该向量将填充不同的结构对象。

do{
   if()
   {
     sound_device_t newDevice;  //<--- Why is this the same mem address each iteration?
                                //I thought it would be destroyed when it's scope was (the if block)


     const char * newPath;
     someFunction(&newPath); //puts a string into newPath
     newDevice.firstString = newPath;   //<-- This works.

     QString otherPath(const char *);
     //...some QString manipulation...//
     newDevice.secondString = otherPath.toLocal8Bit().data();  //<--this doesn't

     vector_of_structs -> push_back(newDevice);

   }
}while (...)

我的印象是 push_back 将参数结构的值复制到自己的版本中。为什么 QString 会给我带来问题?我使用 QString 是因为它有一些很好的字符串操作函数(即插入和部分),但如果我需要一些有用的东西,我会交换它。

我也尝试过将 QString 的数据放入 char * 中,然后将其 strcpy'ing 到结构中,但结果相同。每次迭代都会重写 newDevice.secondString。

【问题讨论】:

  • 只是出于好奇:有什么理由不使用 append 而不是 push_back?另外,为什么不使用 QStringList? QString otherPath(const char *); 无效,顺便说一句。另外,你能总结一下“不起作用”是什么意思吗? newDevice.secondString 是 char* 吗?
  • 存储const char* 以备后用...为什么不使用std::string 或者在这种情况下使用QStringsomeFunction(const char**) 是否在堆上分配?
  • 感谢您回复@LaszloPapp。我在 std::vector 类中看不到 append 。我在看this page. 我从来没有听说过QStringList。 :) 不过,大多数情况下,我试图避免使用太多 Qt 库,因为我试图让我的程序尽可能小。
  • 嘿@Zaiborg。我开始使用 const char * 因为我正在与 DBUS 交互并且所有函数都使用 const char *。在这种情况下,我尝试使用 std::string ,但它也不起作用。我不知道 someFunction() 是否在堆上分配。我该如何检查? (这是一个 DBUS 功能。)
  • 请不要编辑问题以表明它已解决,或者您已为其添加了新答案。

标签: c++ qt pointers vector struct


【解决方案1】:

QByteArray::data() 仅在 ByteArray 未更改时才有效。破坏临时性正在改变。

换句话说,在newDevice.secondString = otherPath.toLocal8Bit().data(); 行的分号之后,toLocal8Bit 返回的 QByteArray 被销毁,存储的数组 deleted。

【讨论】:

  • 嘿@ratchet 怪胎。喔好吧。我在 QString 文档中看到了类似的内容,但不确定。有关如何解决它的任何建议?
  • @MrUser 分配您自己的缓冲区或将 QString 存储在结构中,我更喜欢存储 QString,这样我就不必自己处理内存管理(对 firstString 也一样)
【解决方案2】:

您的代码有几个问题:

  • if 无条件语句 (!)

  • 无效构造:QString otherPath(const char *);您可能想要一个类似于“newPath”的“otherPath”变量。

  • 您正在将 qt 类型与 std 容器混合。你应该看看 QStringList。

  • 不需要的指针用法:newDevice.secondString = otherPath.toLocal8Bit().data();

最后一个尤其​​重要,因为您在下一次迭代之前破坏了 otherPath。解决方案是在其中使用深层副本。

我会这样写:

do {
   if(cond) {
     sound_device_t newDevice;    

     const char * newPath;
     someFunction(&newPath);
     newDevice.firstString = newPath;

     // Get other path
     QString otherPath(otherPath);
     //...some QString manipulation...
     newDevice.secondQString = otherPath;
     // or: strcpy( newDevice.secondString, otherPath.toLocal8Bit().data());

     vector_of_structs->push_back(newDevice);

   }
} while (...)

话虽如此,根据您要执行的操作,QtMultiMedia 可能更适合整体用于您的声音设备。只要dbus去,还有QtDBus附加模块。

【讨论】:

  • 当然我的 if() 有条件。 :) 我只是没有包括它,因为我认为这对这个问题并不重要。在我发送给 QString 构造函数的代码中还分配了一个 const char *。为简单起见,我再次输入QString otherPath(const char *);。第三,我认为我不能只将 QString 对象发送到 const char *。首先需要将它转换为 const char * (这是我认为 toLatin1().data() 所做的)
  • @MrUser:你没有仔细阅读。 newDevice.secondQString,但是如果您出于某种原因真的想避免这种情况,strcpy 是您手动分配的朋友,就像答案中已经提到的那样...您没有仔细阅读,你有没有……
  • 感谢您的所有编辑,@Laszlo Papp。当你发布它们时,我正在阅读它们。我很想使用 strcpy,但这是不可能的,因为 secondString 是 const char * 并且 strcpy 只允许复制到非常量 char *。我将尝试将其设为非常量 char * 并报告。
  • 好吧,你可以这样做,但它更丑:char *tmp_data = new char[otherPath.toLocal8Bit().size()]; strcpy(tmp_data, otherPath.toLocal8Bit().constData()); newDevice.secondString = const_cast&lt;const char*&gt;(tmp_data);strcpy( const_cast&lt;char*&gt;(newDevice.secondString), otherPath.toLocal8Bit().data());
【解决方案3】:

感谢所有帮助的人。我得到了原始代码,只需进行一次调整:

newDevice.secondString = otherPath.toLocal8Bit().data();

应该改为

newDevice.secondString = strdup(otherPath.toLocal8Bit().data());

正如@ratchet 怪胎所建议的那样,这直接进行缓冲区分配。 strcpy() 不起作用,因为它仍然将 newDevice.secondString 与 QByteArray 连接起来,就像 toLatin1().data() 一样。

【讨论】:

  • 嗯? strcpy 工作正常吗? strcpy 的全部意义在于断开连接,但您确实应该在代码中摆脱这种糟糕的设计,即处理低级字符串,恕我直言。
  • 我想我没明白你的意思。我说 strcpy 不能正常工作。我正在使用低级字符串,因为这是 DBUS 提供给我的接口,正如我上面已经说过的。不过,感谢您的持续关注。感谢您的跟进。
  • 我认为你不明白 strcpy 的作用; sound_device_t 不是 dbus 提供的
猜你喜欢
  • 2021-01-21
  • 2015-03-23
  • 1970-01-01
  • 2014-12-12
  • 2021-07-11
  • 2012-05-28
  • 2014-10-11
  • 2019-06-18
  • 1970-01-01
相关资源
最近更新 更多