将两个字节变为short时会堆坏。 C ++

时间:2013-03-01 23:05:05

标签: c++ pointers memory dealloc heap-corruption

我正在使用C ++开发一个程序,并在运行此代码时遇到此错误:

short readshort() {
    short val=0;
    (&val)[1]=data.front(); data.pop_front();
    (&val)[0]=data.front(); data.pop_front();
    return val;
}

这是我得到的错误:

Run-Time Check Failure #2 - Stack around the variable 'val' was corrupted.

我现在应该提一下,“data”是用std :: list data定义的;

我想我知道问题是什么,但我想不出一个简单的解决方案。我认为这个错误是由于“val”存储在堆栈中而不是作为指针。当我尝试通过“val”访问数据指针时,我收到此错误。

我想到的解决方案是像这样分配“val”:

short readshort() {
    short* val=new short;
    val[1]=data.front(); data.pop_front();
    val[0]=data.front(); data.pop_front();
    return *val;
}

但是一旦我返回它,我就看不到删除“val”的方法,而不必每次都在函数外删除它。 有没有办法可以在C ++中完成内存泄漏?我之前没有看到有人使用“(& val)[1]”将变量类型(例如short)拆分为字节,并且想知道这是因为它是否会引起一些问题,或者它只是不是已知方法?

回到真正的问题,如何将这两个字节变为短(或大数据类型)?还有比我尝试过的更好的方法吗?

最后一件事,我知道java有一个自动垃圾收集器,可以自动清除内存泄漏。 C ++是否提供相同类型的设备?我听说过Smart Pointers,但我不知道它们是什么;)

4 个答案:

答案 0 :(得分:2)

这是安全和简单的:

int16_t readshort()
{
    union { int16_t s; char val[2]; } u;
    u.val[1]=data.front(); data.pop_front();
    u.val[0]=data.front(); data.pop_front();
    return *(int16_t*)u.val;
}

答案 1 :(得分:1)

(&val)[1]=data.front()执行(&val)[1]错误,您正在将下一个内存位置写入未定义的val

(&val)[i]表示*(&val + i )
(&val)[0]表示*(&val + 0 ) = *(&val)此罚款 (&val)[1]表示*(&val + 1 ) =但这是错误,因为您的声明是short val所以我们只能访问val位置。

+----+----+----+---+---+----+----+----+---+----+ 
|val      |        |
+----+----+----+---+---+----+----+----+---+---+----+  
 201   202  203 204 205 206  207   208 209 210  211
  ^           ^ 
   |          |
 &val         (&val + 1) 
              its not defined.   

你可以使用@Carl Norum建议的tyoecase。我只是写第二种形式来做这件事。

char *ptr = (char*)&val;

ptr[0]=data.front()
ptr[1]=data.front()

但是如果你需要val那么短并且想要访问单个字节。我想建议union

union Data{
 short val;
 char ch1;
 char ch2;
};

union Data d; 

d.ch1 = data.front()
d.ch2 = data.front()

答案 2 :(得分:1)

您需要将指针强制转换为char *。

((char *)(&val))[1]=data.front();
((char *)(&val))[0]=data.front();

我认为在你的情况下:(& val)[1] = data.front();你把数据写入第二短。结果你得到错误。

答案 3 :(得分:0)

(&val)[1]访问您尚未分配的内存。 Bam - 未定义的行为。你的两个例子都有同样的问题。

如果要像这样分割字节,则需要使用char指针来访问各个字节:

short readshort() {
    short val=0;
    ((char *)&val)[1]=data.front(); data.pop_front();
    ((char *)&val)[0]=data.front(); data.pop_front();
    return val;
}

但是,这段代码非常难看。为什么不呢:

short readshort() {
    short val=0;
    val  = data.front() << 8; data.pop_front();
    val |= data.front() << 0; data.pop_front();
    return val;
}

根据字节顺序,您可能需要在那里交换80的位置。