문제

I am developing a program in C++ and encounter this error when I run this code:

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

This is the error I get:

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

I should mention now, that "data" is defined with std::list data;

I think I know what is the problem, but I cannot think of an easy solution. I think this error is cause by the "val" being stored in the stack, and not as a pointer. When I try to access the data pointer by "val" I get this error.

The solution I thought about was allocating "val" like this:

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

But I can't see a way to delete "val" once I have returned it without having to delete it outside the function every time. Is there a way this can be done in C++ wihtout a memory leak? I havn't seen anyone split a variable type (e.g. short) into bytes using "(&val)[1]" before, and wondered if this was because it gave rise to a number of problems, or is it just not a known method?

Coming back to the real question, how can I make these two bytes into short (or large data type)? And is there a better way of doing this than what I have tried?

One last thing, I know that java has an automatic garbage collector that cleans up memory leaks automatically. Does C++ offer the same kind of device? I heard somthing about Smart Pointers, but I don't know what they are ;)

도움이 되었습니까?

해결책

This is safe and simple:

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;
}

다른 팁

You need to cast your pointer to char*.

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

I think in your case: (&val)[1]=data.front(); you write data to second short. As result you get error.

(&val)[1]=data.front() an error by doing (&val)[1] you are writing next memory location to val that is not defined.

(&val)[i] means *(&val + i )
(&val)[0] means *(&val + 0 ) = *(&val) this fine
(&val)[1] means *(&val + 1 ) = But this is error because your declaration is short val so we can access only val location.

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

you could use tyoecase like @Carl Norum suggested. I am just writing second form to do this.

char *ptr = (char*)&val;

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

But if your need val as short and wanted to access individual bytes. I would like to suggest union:

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

union Data d; 

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

(&val)[1] accesses memory you don't have allocated. Bam - undefined behaviour. Both of your examples have the same problem.

If you want to split bytes like that, you need to use char pointers to access the individual bytes:

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

This code is really pretty ugly, though. Why not just:

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

Depending on endianness, you may need to swap the positions of the 8 and 0 there.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top