【问题标题】:How to solve this bus error?如何解决这个总线错误?
【发布时间】:2012-09-11 10:53:09
【问题描述】:

以下代码在一个程序中运行良好,并且 导致另一个总线错误

    char *temp1;
    temp1=(char*)malloc(2);
    for(b=3;b>=0;b--)
       {
       sprintf(temp1,"%02x",s_ip[b]);
       string temp2(temp1); 
       temp.append(temp2);
       } 

s_ip[b] 是 byte 类型, temp 是一个字符串。是什么导致了这个总线错误,我该如何解决这个问题? 此外,这种奇怪行为的原因是什么?

【问题讨论】:

  • 请注意,根据 s_ip[b] 中的实际值,这可能会比您预期的 2 位数还要多,因此您应该考虑使用 snprintf 增加一些安全性
  • @sjsam,s_ip 有 4 个元素吗?
  • @sjsam,那么s_ip 的唯一有效索引是01,但发布的for 循环将访问3, 2, 1, 0。将 for 循环更改为 for (b = 1; b >= 0; b--)
  • 你试过调试吗? SIGBUS 应该会指出问题所在。
  • @rtlgrmpf :这似乎是件好事..

标签: c++ bus-error


【解决方案1】:

temp 缓冲区的长度必须为 3 个字符,因为sprintf() 将在两个十六进制字符后附加一个空终止符:

char temp1[3];

似乎没有理由使用动态分配的内存。请注意,您可以使用 std::string::append() 避免创建名为 temp2 的临时 string

temp.append(temp1, 2);

另一种方法是避免使用 sprintf() 并在 IO 操纵器中使用 std::ostringstream

#include <sstream>
#include <iomanip>

std::ostringstream s;

s << std::hex << std::setfill('0');

for (b = 3; b >= 0; b--)
{
    s << std::setw(2) << static_cast<int>(s_ip[b]);
}

然后使用s.str()获取std::string实例。

【讨论】:

  • 他甚至可以通过 resize() 字符串然后直接用 snprintf 写入它来避免任何临时性...
  • @PlasmaHH,我认为这是未定义的行为?
  • @PlasmaHH,你能发布你想要的代码吗?如果你直接修改std::string 的内部结构并说它缓存了它的大小,std::string 实例不会失效吗?
  • 你只是做一些事情 N=s.size(); s.resize(N+p); r=snprintf(&s[N],p,blah); s.resize(N+r);。我不知道您所说的“缓存大小”是什么意思
  • 我以为这就是你的意思。我一直认为这是非法的。如果没有,那么我今天学到了一些东西。
【解决方案2】:

2个字符的字符串实际上需要3个字节,因为在字符串的末尾还有一个终止符'\0'

【讨论】:

  • 谢谢。我已经更改了它,但我仍然遇到总线错误。还有其他原因导致此错误吗??
猜你喜欢
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
相关资源
最近更新 更多