0

I'am really stuck with this C++ error:

    template<typename T>
    void Shift(T* Data, const ulong& Length, long Offset) const
    {
        if((!Data) || (!Length))
            return;

        if(Offset < 0)
            Offset = (Length-1) - ((-Offset-1) % Length);
        else
            Offset %= Length;

        if(!Offset)
            return;

        int TSize = sizeof(T);

        T* Shifter = new T[Length];

        if(Shifter)
        {
            memcpy(Shifter, Data + TSize * Offset, TSize * (Length - Offset));
            memcpy(Shifter + TSize * (Length - Offset), Data, TSize * Offset); //fails
            memcpy(Data, Shifter, TSize * Length);

            delete[] Shifter;
        }
    }

Well, fail is:

77CD0575 ntdll!TpWaitForAlpcCompletion() (C:\Windows\system32\ntdll.dll:??)

0028D640 ?? () (??:??)

77CB57C2 ntdll!RtlLargeIntegerDivide() (C:\Windows\system32\ntdll.dll:??)

003E1030 ?? () (??:??)

77C92A8A ntdll!RtlCopyExtendedContext() (C:\Windows\system32\ntdll.dll:??)

?? ?? () (??:??)

T is either byte of short, btw.

2 Answers2

8

You got the pointer arithmetics wrong. Let's say:

T* p = new T[10];

To get to the n'th element, you have to use

T* nth = p + n;

In your memcpy arguments you use it like

T* nth = p + sizeof(T) * n;

which will obviously be out of bounds at times.

Timbo
  • 27,472
  • 11
  • 50
  • 75
  • But he can also convert the data and shifter pointer to void* as malloc and memcpy use void* in their prototypes. less expressive than C++ but... – alexbuisson Dec 13 '13 at 12:35
  • 1
    @alexbuisson Not to void but to some byte-sized type, yes. void* does not allow pointer arithmetics. – Timbo Dec 13 '13 at 12:36
3

in memcpy you are using Data + Offset*TSize which is incorrect when you say Data + 1 on case of an int the it actually takes 4 bytes, so you dont have to specify Tsize in case of pointer. Modify your memcpy code like this

memcpy(Shifter, Data + Offset, TSize * (Length - Offset));
memcpy(Shifter + (Length - Offset), Data, TSize * Offset); //fails if TSize is greater than 1
memcpy(Data, Shifter, TSize * Length);

Better explained by Timbo

kunal
  • 956
  • 9
  • 16