【问题标题】:Why do all C++ array elements get set despite addressing just one item?为什么尽管只寻址一项,但所有 C++ 数组元素都会被设置?
【发布时间】:2019-04-29 02:03:53
【问题描述】:

我有一个结构数组,我需要将 CString 转换为 char 数组。此转换针对 1000 个数据点进行,并将输出写入新数组。所以我的问题是:我有一个 for 循环遍历 CStrings 数组并将它们转换为 char 数组并将其写入我的“新”数组。问题是每次迭代都会将新转换的char 数组写入所有先前的数组元素。例如newArr[0] = oldArr[0] = 工作。 newArr[1] = oldArr[1] 但现在 newArr[0] 也 = oldArr[1]。然后是newArr[2] = oldArr[2],但又是newArr[0]newArr[1]newArr[2] = oldArr[2]

我的代码如下:

    for (size_t i = 0; i < MAX_TAGS; i++)
{
    char nodeStr[40];
    strcpy_s(nodeStr, (strlen(theConf.confP[i].nodeID) + 1), theConf.confP[i].nodeID);
    monitoredNodes[i] = UA_NODEID_STRING(theConf.confP[i].namespaceIndex, nodeStr);
}

我想我在这里做错了,但我尝试了各种方法,包括查看编译器优化,但每次都是同样的问题,尽管我按索引设置了一个数组项,但所有以前的数组项似乎也都被写入了.

【问题讨论】:

  • 这不是strcpy_s的正确使用方式,第二个参数应该是目标(nodeStr)的大小。
  • UA_NODEID_STRING 是做什么的?

标签: c++ arrays char c-strings


【解决方案1】:

您在每次迭代循环中不断创建和销毁char nodeStr[40] 缓冲区。该缓冲区是在先前迭代的缓冲区所在的同一堆栈地址创建的,这就是为什么看起来您覆盖了以前的值。您可能希望该缓冲区持续存在而不是被覆盖。

您可能不需要复制字符串,只需使用其内部零终止缓冲区即可:

for(size_t i = 0; i < MAX_TAGS; ++i) {
    char const* nodeStr = theConf.confP[i].nodeID.GetBuffer();
    monitoredNodes[i] = UA_NODEID_STRING(theConf.confP[i].namespaceIndex, nodeStr);
}

如果UA_NODEID_STRING 创建/格式化一个新字符串,最好按值返回CStringstd::string 并将monitoredNodes 设为这些数组,例如CString monitoredNodes[MAX_TAGS];.

【讨论】:

  • 感谢您的帮助,成功了。我知道 char nodeStr[40] 错误地位于循环内部,但我也以相同的行为在外部尝试过。就像数组元素一直指向转换后的字符串一样。您的建议对我有所帮助,现在正在发挥作用。再次感谢!
  • 该缓冲区可能在先前迭代的缓冲区所在的同一堆栈地址创建,并且无法保证在此期间该地址处的数据发生了什么。最好避免这种低级的声明。
  • @LightnessRacesinOrbit 如果缓冲区是在不同的地方创建的,那么 for 循环最终会耗尽堆栈。您可能希望指定在不同位置创建该缓冲区的条件。我能想到一个:alloca 在循环内。
  • @MaximEgorushkin 不过这里没人这样做
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
  • 2023-03-11
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
相关资源
最近更新 更多