locked
std::vector [] operator compiler optimization problem RRS feed

  • Question

  • In my small C++ test program, I have a std::vector with 10 elements in it. A previous statement has created an index variable = 3. I then access the std::vector with the index value using the [] operator. When I compile the source file in release mode (/02), it is generating the following assembly for that portion of the code:

    int v3 = v[nRandomB]; (source line)

    00007FF7D45D1F25  movsxd      rcx,ebx  
    00007FF7D45D1F28  mov         rdx,0FFFFFFFC00000000h  
    00007FF7D45D1F32  lea         rax,[r15+rdx]  
    00007FF7D45D1F36  mov         r9d,dword ptr [rax+rcx*4]  

    I am getting an access violation exception when the line lea, rax[r15+rdx] executes, rax is incorrect to access v[3]. It is 0x00000237EB6680A0, which is incorrect. So when the mov         r9d,dword ptr [rax+rcx*4] instruction executes, it attempting to access unallocated memory. 

    The strange thing here is that r15 contains the address &v[0] which is correct (for this instance is 0x0000023BEB6680A0). The address of the value (v[3]) is located at 0x0000023BEB6680AC but the rdx in lea rax,[r15 + rdx] is causing it to shift to an incorrect area.

    Why is it generating this code that causes a crash?

    Wednesday, January 24, 2018 5:22 PM

All replies

  • Show the C++ source code.


    Sam Hobbs
    SimpleSamples.Info

    Wednesday, January 24, 2018 5:44 PM
  • Extra lines are to ensure code is generated in release mode and optimization /O2

    #include <QtCore/QCoreApplication>
    #include <random>
    #include <iostream>

    using namespace std;

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);

        std::vector<int> v;
        for (auto i = 0; i < 10; i++)
        {
            v.push_back(i);
        }
        std::random_device Rd;
        std::mt19937 Gen(Rd());
        std::uniform_int_distribution<int> Dis(0, v.size() - 1);

        for (auto i = 0; i < 10; i++)
        {
            printf("&v[%d] = %p\n", i, &v[i]);
        }

        int nRandomA = Dis(Gen);
        int nRandomB = Dis(Gen);
        int x = 1; 
        int y = 2;
        int nRandomA1 = x*y;
        int x1 = 2;
        int y1 = 2;
        int nRandomB1 = x1 * y1;
        printf("&v[0] = %p nRandomA = %d nRandomB = %d\n", &v[0], nRandomA, nRandomB);

        int v3 = v[nRandomB];     // line show in previous post, which is the one that is crashing.
        int v4 = v[nRandomB1];
        int v2 = v[nRandomA1];
        int v1 = v[nRandomA];
        int v5 = v1 * v2;
        int v6 = v3 * v4;
        int v7 = v5 * v6;
        printf("v1 = %d v2 = %d v3 = %d v4 = %d\ v5 = %d v6 = %d v7 = %d", v1, v2, v3, v4, v5, v6, v7);

        return a.exec();

    Wednesday, January 24, 2018 6:11 PM
  • And what is the value of nRandomB?

    If this truly is a bug in C++ then it will really help to have a small sample program that recreates the problem that others (especially Microsoft) can build and test.

    Also, if you go to "Help" | "Send Feedback" | "Report a Problem..." then you can search for the problem existing already (has been reported). If it has not been reported then having the sample program that shows the problem is critical to reporting it.



    Sam Hobbs
    SimpleSamples.Info

    Wednesday, January 24, 2018 6:32 PM
  • nRandomB was 3 at the time I ran the program.

    This was occuring in a larger application and I pulled it out into this test program. The curious assembly instructions generated when the source line "int v3 = v[nRandomB]" is compiled are:

    mov         rdx,0FFFFFFFC00000000h

    lea         rax,[r15+rdx] 

    Adding rdx to r15 is causing the base address (rax) to move outside of the memory of the vector v (addresses are given in the first post), which is causing it to crash when the next assembly is executed. 

    mov         r9d,dword ptr [rax+rcx*4]

    I thought maybe somebody might know why the compiler is generating those instructions that's causing to move outside the memory bounds of the vector.

    I verified itt does not happen in debug mode or if you turn off optimizations. I checked the generated code in both cases and the instructions mov         rdx,0FFFFFFFC00000000h is not generated. 

      

    Wednesday, January 24, 2018 7:40 PM
  • I will leave this for someone else to continue. I will test it if you are able to create a stand-alone sample that recreates the problem.

    It has been about a quarter century since I have done assembler but I understand generally what you are saying about the machine instructions. If the value 0FFFFFFFC00000000h is in the code section then we know it cannot have been clobbered during execution and I understand that it is suspicious.



    Sam Hobbs
    SimpleSamples.Info

    Wednesday, January 24, 2018 8:27 PM
  • Here is a windows console test application created with VS 2017 on Windows 10. It's built in release mode with optimizations set to /O2 (Maximize Speed). The only dependency is <random> from the standard library. This is used to generate the index so the compiler doesn't optimize it away. I print the addresses of all indices with v, so it is clear where the memory for v exists.

    // ConsoleApplication1.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include <random>


    int main()
    {
        std::vector<int> v;
        for (auto i = 0; i < 10; i++)
        {
            v.push_back(i);
        }
        for (auto i = 0; i < 10; i++)
        {
            printf("&v[%d] = %p\n", i, &v[i]);
        }

        std::random_device Rd;
        std::mt19937 Gen(Rd());
        std::uniform_int_distribution<int> Dis(0, v.size() - 1);
        int index = Dis(Gen);
        printf("index = %d", index);
        int value = v[index];
        printf("value = %d", value);
        return 0;
    }

    Here is the source intermixed with the generated assembly. I have bolded the source lines, but it can be daunting to follow; however, the line of interest is:

        int value = v[index];

    because that's where the offending assembly instruction is generated. See previous posts for detailed explanation of what is occurring. There has to be a reason why the compiler is generating that instruction under those conditions.

    --- No source file -------------------------------------------------------------
    00007FF6A7040F67  add         byte ptr [rax],al  
    00007FF6A7040F69  add         byte ptr [rax],al  
    00007FF6A7040F6B  add         byte ptr [rax],al  
    00007FF6A7040F6D  add         byte ptr [rax],al  
    00007FF6A7040F6F  add         byte ptr [rax],al  
    00007FF6A7040F71  add         byte ptr [rax],al  
    00007FF6A7040F73  add         byte ptr [rax],al  
    00007FF6A7040F75  add         byte ptr [rax],al  
    00007FF6A7040F77  add         byte ptr [rax],al  
    00007FF6A7040F79  add         byte ptr [rax],al  
    00007FF6A7040F7B  add         byte ptr [rax],al  
    00007FF6A7040F7D  add         byte ptr [rax],al  
    00007FF6A7040F7F  add         byte ptr [rax],al  
    00007FF6A7040F81  add         byte ptr [rax],al  
    00007FF6A7040F83  add         byte ptr [rax],al  
    00007FF6A7040F85  add         byte ptr [rax],al  
    00007FF6A7040F87  add         byte ptr [rax],al  
    00007FF6A7040F89  add         byte ptr [rax],al  
    00007FF6A7040F8B  add         byte ptr [rax],al  
    00007FF6A7040F8D  add         byte ptr [rax],al  
    00007FF6A7040F8F  add         byte ptr [rax],al  
    00007FF6A7040F91  add         byte ptr [rax],al  
    00007FF6A7040F93  add         byte ptr [rax],al  
    00007FF6A7040F95  add         byte ptr [rax],al  
    00007FF6A7040F97  add         byte ptr [rax],al  
    00007FF6A7040F99  add         byte ptr [rax],al  
    00007FF6A7040F9B  add         byte ptr [rax],al  
    00007FF6A7040F9D  add         byte ptr [rax],al  
    00007FF6A7040F9F  add         byte ptr [rax],al  
    00007FF6A7040FA1  add         byte ptr [rax],al  
    00007FF6A7040FA3  add         byte ptr [rax],al  
    00007FF6A7040FA5  add         byte ptr [rax],al  
    00007FF6A7040FA7  add         byte ptr [rax],al  
    00007FF6A7040FA9  add         byte ptr [rax],al  
    00007FF6A7040FAB  add         byte ptr [rax],al  
    00007FF6A7040FAD  add         byte ptr [rax],al  
    00007FF6A7040FAF  add         byte ptr [rax],al  
    00007FF6A7040FB1  add         byte ptr [rax],al  
    00007FF6A7040FB3  add         byte ptr [rax],al  
    00007FF6A7040FB5  add         byte ptr [rax],al  
    00007FF6A7040FB7  add         byte ptr [rax],al  
    --- No source file -------------------------------------------------------------
    00007FF6A7040FB9  add         byte ptr [rax],al  
    00007FF6A7040FBB  add         byte ptr [rax],al  
    00007FF6A7040FBD  add         byte ptr [rax],al  
    00007FF6A7040FBF  add         byte ptr [rax],al  
    00007FF6A7040FC1  add         byte ptr [rax],al  
    00007FF6A7040FC3  add         byte ptr [rax],al  
    00007FF6A7040FC5  add         byte ptr [rax],al  
    00007FF6A7040FC7  add         byte ptr [rax],al  
    00007FF6A7040FC9  add         byte ptr [rax],al  
    00007FF6A7040FCB  add         byte ptr [rax],al  
    00007FF6A7040FCD  add         byte ptr [rax],al  
    00007FF6A7040FCF  add         byte ptr [rax],al  
    00007FF6A7040FD1  add         byte ptr [rax],al  
    00007FF6A7040FD3  add         byte ptr [rax],al  
    00007FF6A7040FD5  add         byte ptr [rax],al  
    00007FF6A7040FD7  add         byte ptr [rax],al  
    00007FF6A7040FD9  add         byte ptr [rax],al  
    00007FF6A7040FDB  add         byte ptr [rax],al  
    00007FF6A7040FDD  add         byte ptr [rax],al  
    00007FF6A7040FDF  add         byte ptr [rax],al  
    00007FF6A7040FE1  add         byte ptr [rax],al  
    00007FF6A7040FE3  add         byte ptr [rax],al  
    00007FF6A7040FE5  add         byte ptr [rax],al  
    00007FF6A7040FE7  add         byte ptr [rax],al  
    00007FF6A7040FE9  add         byte ptr [rax],al  
    00007FF6A7040FEB  add         byte ptr [rax],al  
    00007FF6A7040FED  add         byte ptr [rax],al  
    00007FF6A7040FEF  add         byte ptr [rax],al  
    00007FF6A7040FF1  add         byte ptr [rax],al  
    00007FF6A7040FF3  add         byte ptr [rax],al  
    00007FF6A7040FF5  add         byte ptr [rax],al  
    00007FF6A7040FF7  add         byte ptr [rax],al  
    00007FF6A7040FF9  add         byte ptr [rax],al  
    00007FF6A7040FFB  add         byte ptr [rax],al  
    00007FF6A7040FFD  add         byte ptr [rax],al  
    00007FF6A7040FFF  add         byte ptr [rax+57h],al  
    --- e:\dev\acepremier\ap4-core-ids\clients\aceframe\consoleapplication1\consoleapplication1.cpp 
    // ConsoleApplication1.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include <random>


    int main()
    {
    00007FF6A7041002  mov         eax,13F0h  
    00007FF6A7041007  call        __chkstk (07FF6A70426B0h)  
    00007FF6A704100C  sub         rsp,rax  
    00007FF6A704100F  mov         qword ptr [rsp+28h],0FFFFFFFFFFFFFFFEh  
    00007FF6A7041018  mov         qword ptr [rsp+1400h],rbx  
    // ConsoleApplication1.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include <random>


    int main()
    {
    00007FF6A7041020  mov         qword ptr [rsp+1408h],rsi  
    00007FF6A7041028  mov         rax,qword ptr [__security_cookie (07FF6A7045000h)]  
    00007FF6A704102F  xor         rax,rsp  
    00007FF6A7041032  mov         qword ptr [rsp+13E0h],rax  
    00007FF6A704103A  xor         eax,eax  
    00007FF6A704103C  xorps       xmm0,xmm0  
        std::vector<int> v;
    00007FF6A704103F  movdqu      xmmword ptr [v],xmm0  
    00007FF6A7041045  mov         qword ptr [rsp+40h],rax  
        for (auto i = 0; i < 10; i++)
    00007FF6A704104A  mov         dword ptr [i],eax  
    00007FF6A704104E  xchg        ax,ax  
        {
            v.push_back(i);
    00007FF6A7041050  lea         rdx,[i]  
    00007FF6A7041055  lea         rcx,[v]  
    00007FF6A704105A  call        std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64> (07FF6A7041210h)  
        for (auto i = 0; i < 10; i++)
    00007FF6A704105F  mov         eax,dword ptr [i]  
    00007FF6A7041063  inc         eax  
    00007FF6A7041065  mov         dword ptr [i],eax  
    00007FF6A7041069  cmp         eax,0Ah  
    00007FF6A704106C  jl          main+50h (07FF6A7041050h)  
        }
        for (auto i = 0; i < 10; i++)
    00007FF6A704106E  xor         ebx,ebx  
    00007FF6A7041070  mov         rsi,qword ptr [v]  
    00007FF6A7041075  mov         rdi,rsi  
    00007FF6A7041078  nop         dword ptr [rax+rax]  
        {
            printf("&v[%d] = %p\n", i, &v[i]);
    00007FF6A7041080  mov         r8,rdi  
    00007FF6A7041083  mov         edx,ebx  
    00007FF6A7041085  lea         rcx,[string "&v[%d] = %p\n" (07FF6A7043318h)]  
    00007FF6A704108C  call        printf (07FF6A7041610h)  
        }
        for (auto i = 0; i < 10; i++)
    00007FF6A7041091  inc         ebx  
    00007FF6A7041093  add         rdi,4  
    00007FF6A7041097  cmp         ebx,0Ah  
    00007FF6A704109A  jl          main+80h (07FF6A7041080h)  
        }

        std::random_device Rd;
        std::mt19937 Gen(Rd());
    00007FF6A704109C  call        qword ptr [__imp_std::_Random_device (07FF6A7043080h)]  
    00007FF6A70410A2  mov         dword ptr [rsp+13D4h],0FFFFFFFFh  
    00007FF6A70410AD  mov         dword ptr [rsp+54h],eax  
    00007FF6A70410B1  mov         r8d,1  
        return 0;
    00007FF6A70410B7  mov         edx,r8d  
    00007FF6A70410BA  nop         word ptr [rax+rax]  
        }

        std::random_device Rd;
        std::mt19937 Gen(Rd());
    00007FF6A70410C0  mov         ecx,eax  
    00007FF6A70410C2  shr         ecx,1Eh  
    00007FF6A70410C5  xor         ecx,eax  
    00007FF6A70410C7  imul        eax,ecx,6C078965h  
    00007FF6A70410CD  add         eax,r8d  
    00007FF6A70410D0  mov         dword ptr [rsp+rdx*4+54h],eax  
    00007FF6A70410D4  inc         r8d  
    00007FF6A70410D7  inc         rdx  
    00007FF6A70410DA  cmp         rdx,270h  
    00007FF6A70410E1  jl          main+0C0h (07FF6A70410C0h)  
    00007FF6A70410E3  mov         dword ptr [Gen],270h  
        std::uniform_int_distribution<int> Dis(0, v.size() - 1);
    00007FF6A70410EB  mov         rbx,qword ptr [rsp+38h]  
    00007FF6A70410F0  sub         rbx,rsi  
    00007FF6A70410F3  sar         rbx,2  
    00007FF6A70410F7  dec         ebx  
        int index = Dis(Gen);
    00007FF6A70410F9  cmp         ebx,0FFFFFFFFh  
    00007FF6A70410FC  jne         main+10Ch (07FF6A704110Ch)  
    00007FF6A70410FE  lea         rcx,[Gen]  
    00007FF6A7041103  call        std::mersenne_twister<unsigned int,32,624,397,31,2567483615,11,7,2636928640,15,4022730752,18>::operator() (07FF6A7041470h)  
    00007FF6A7041108  mov         ebx,eax  
    00007FF6A704110A  jmp         main+14Bh (07FF6A704114Bh)  
    00007FF6A704110C  lea         edi,[rbx+1]  
    00007FF6A704110F  nop  
    00007FF6A7041110  xor         r8d,r8d  
    00007FF6A7041113  xor         eax,eax  
    00007FF6A7041115  test        ebx,ebx  
    00007FF6A7041117  je          main+129h (07FF6A7041129h)  
    00007FF6A7041119  lea         rcx,[Gen]  
    00007FF6A704111E  call        std::mersenne_twister<unsigned int,32,624,397,31,2567483615,11,7,2636928640,15,4022730752,18>::operator() (07FF6A7041470h)  
    00007FF6A7041123  mov         r8d,eax  
    00007FF6A7041126  or          eax,0FFFFFFFFh  
    00007FF6A7041129  xor         edx,edx  
    00007FF6A704112B  div         eax,edi  
    00007FF6A704112D  mov         r9d,edx  
    00007FF6A7041130  mov         ecx,eax  
    00007FF6A7041132  xor         edx,edx  
    00007FF6A7041134  mov         eax,r8d  
    00007FF6A7041137  div         eax,edi  
    00007FF6A7041139  cmp         eax,ecx  
    00007FF6A704113B  jb          main+142h (07FF6A7041142h)  
    00007FF6A704113D  cmp         r9d,ebx  
    00007FF6A7041140  jne         main+110h (07FF6A7041110h)  
    00007FF6A7041142  xor         edx,edx  
    00007FF6A7041144  mov         eax,r8d  
    00007FF6A7041147  div         eax,edi  
    00007FF6A7041149  mov         ebx,edx  
        printf("index = %d", index);
    00007FF6A704114B  mov         edx,ebx  
    00007FF6A704114D  lea         rcx,[string "index = %d" (07FF6A7043328h)]  
    00007FF6A7041154  call        printf (07FF6A7041610h)  
        int value = v[index];
    00007FF6A7041159  movsxd      rcx,ebx  
    00007FF6A704115C  mov         rax,0FFFFFFFC00000000h  
    00007FF6A7041166  add         rax,rsi  
        printf("value = %d", value);
    00007FF6A7041169  mov         edx,dword ptr [rax+rcx*4]  
    00007FF6A704116C  lea         rcx,[string "value = %d" (07FF6A7043338h)]  
    00007FF6A7041173  call        printf (07FF6A7041610h)  
    00007FF6A7041178  nop  
        return 0;
    00007FF6A7041179  test        rsi,rsi  
    00007FF6A704117C  je          main+1DBh (07FF6A70411DBh)  
    00007FF6A704117E  mov         rcx,qword ptr [rsp+40h]  
    00007FF6A7041183  sub         rcx,rsi  
    00007FF6A7041186  sar         rcx,2  
    00007FF6A704118A  mov         rax,rsi  
    00007FF6A704118D  mov         rdx,3FFFFFFFFFFFFFFFh  
    00007FF6A7041197  cmp         rcx,rdx  
    00007FF6A704119A  ja          main+202h (07FF6A7041202h)  
    00007FF6A704119C  lea         rdx,[rcx*4]  
    00007FF6A70411A4  cmp         rdx,1000h  
    00007FF6A70411AB  jb          main+1D3h (07FF6A70411D3h)  
    00007FF6A70411AD  lea         rcx,[rdx+27h]  
    00007FF6A70411B1  cmp         rcx,rdx  
    00007FF6A70411B4  jbe         main+202h (07FF6A7041202h)  
    00007FF6A70411B6  mov         rdx,rcx  
    00007FF6A70411B9  test        al,1Fh  
    00007FF6A70411BB  jne         main+202h (07FF6A7041202h)  
    00007FF6A70411BD  mov         rsi,qword ptr [rsi-8]  
    00007FF6A70411C1  cmp         rsi,rax  
    00007FF6A70411C4  jae         main+202h (07FF6A7041202h)  
    00007FF6A70411C6  sub         rax,rsi  
    00007FF6A70411C9  sub         rax,8  
    00007FF6A70411CD  cmp         rax,1Fh  
    00007FF6A70411D1  ja          main+202h (07FF6A7041202h)  
    00007FF6A70411D3  mov         rcx,rsi  
    00007FF6A70411D6  call        operator delete (07FF6A70416A4h)  
    00007FF6A70411DB  xor         eax,eax  
    }
    00007FF6A70411DD  mov         rcx,qword ptr [rsp+13E0h]  
    00007FF6A70411E5  xor         rcx,rsp  
    00007FF6A70411E8  call        __security_check_cookie (07FF6A7041680h)  
    00007FF6A70411ED  lea         r11,[rsp+13F0h]  
    00007FF6A70411F5  mov         rbx,qword ptr [r11+10h]  
    00007FF6A70411F9  mov         rsi,qword ptr [r11+18h]  
    00007FF6A70411FD  mov         rsp,r11  
    00007FF6A7041200  pop         rdi  
    00007FF6A7041201  ret  
        return 0;
    00007FF6A7041202  call        qword ptr [__imp__invalid_parameter_noinfo_noreturn (07FF6A7043188h)]  
    00007FF6A7041208  int         3  
    --- No source file -------------------------------------------------------------
    $LN331:
    00007FF6A7041209  int         3  
    00007FF6A704120A  int         3  
    00007FF6A704120B  int         3  
    00007FF6A704120C  int         3  
    00007FF6A704120D  int         3  
    00007FF6A704120E  int         3  
    00007FF6A704120F  int         3  
    --- c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.12.25827\include\vector 

    private:
    template<class... _Valty>
    void _Emplace_back_with_unused_capacity(_Valty&&... _Val)
    { // insert by perfectly forwarding into element at end, provide strong guarantee
    // Pre: _Has_unused_capacity()
    _Alty_traits::construct(this->_Getal(), _Unfancy(this->_Mylast()), _STD forward<_Valty>(_Val)...);
    _Orphan_range(this->_Mylast(), this->_Mylast());
    ++this->_Mylast();
    }

    public:
    template<class... _Valty>
    decltype(auto) emplace_back(_Valty&&... _Val)
    { // insert by perfectly forwarding into element at end, provide strong guarantee
    00007FF6A7041210  push        rbx  
    00007FF6A7041212  push        rdi  
    00007FF6A7041213  push        r15  
    00007FF6A7041215  sub         rsp,30h  
    00007FF6A7041219  mov         rbx,rcx  
    00007FF6A704121C  mov         r15,rdx  
    if (_Has_unused_capacity())
    00007FF6A704121F  mov         rcx,qword ptr [rcx+10h]  
    00007FF6A7041223  mov         rdi,qword ptr [rbx+8]  
    00007FF6A7041227  cmp         rcx,rdi  
    00007FF6A704122A  je          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+2Eh (07FF6A704123Eh)  
    {
    _Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...);
    00007FF6A704122C  mov         eax,dword ptr [rdx]  
    00007FF6A704122E  mov         dword ptr [rdi],eax  
    00007FF6A7041230  add         qword ptr [rbx+8],4  
    }

    #if _HAS_CXX17
    return (this->_Mylast()[-1]);
    #endif /* _HAS_CXX17 */
    }
    00007FF6A7041235  add         rsp,30h  
    00007FF6A7041239  pop         r15  
    00007FF6A704123B  pop         rdi  
    00007FF6A704123C  pop         rbx  
    00007FF6A704123D  ret  
    }
    else
    { // reallocate
    const size_type _Oldsize = size();
    00007FF6A704123E  mov         rax,qword ptr [rbx]  
    00007FF6A7041241  sub         rdi,rax  
    00007FF6A7041244  mov         qword ptr [rsp+28h],r12  
    00007FF6A7041249  sar         rdi,2  

    if (_Oldsize == max_size())
    00007FF6A704124D  mov         r12,3FFFFFFFFFFFFFFFh  

    if (_Oldsize == max_size())
    00007FF6A7041257  cmp         rdi,r12  
    00007FF6A704125A  je          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+181h (07FF6A7041391h)  
    const size_type _Newcapacity = _Calculate_growth(_Newsize);
    00007FF6A7041260  sub         rcx,rax  
    00007FF6A7041263  mov         qword ptr [rsp+58h],rbp  
    00007FF6A7041268  sar         rcx,2  
    00007FF6A704126C  mov         rax,r12  
    00007FF6A704126F  mov         rdx,rcx  
    00007FF6A7041272  mov         qword ptr [rsp+20h],r14  
    00007FF6A7041277  shr         rdx,1  
    }

    const size_type _Newsize = _Oldsize + 1;
    00007FF6A704127A  lea         r14,[rdi+1]  
    const size_type _Newcapacity = _Calculate_growth(_Newsize);
    00007FF6A704127E  sub         rax,rdx  
    00007FF6A7041281  cmp         rcx,rax  
    00007FF6A7041284  jbe         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+7Bh (07FF6A704128Bh)  
    00007FF6A7041286  mov         rbp,r14  
    00007FF6A7041289  jmp         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+86h (07FF6A7041296h)  
    00007FF6A704128B  lea         rbp,[rdx+rcx]  
    00007FF6A704128F  cmp         rbp,r14  
    00007FF6A7041292  cmovb       rbp,r14  
    00007FF6A7041296  mov         qword ptr [rsp+60h],rsi  
    bool _Emplaced = false;
    const pointer _Newvec = this->_Getal().allocate(_Newcapacity);
    00007FF6A704129B  test        rbp,rbp  
    00007FF6A704129E  jne         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+94h (07FF6A70412A4h)  
    00007FF6A70412A0  xor         esi,esi  
    00007FF6A70412A2  jmp         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+0D9h (07FF6A70412E9h)  
    00007FF6A70412A4  cmp         rbp,r12  
    00007FF6A70412A7  ja          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+187h (07FF6A7041397h)  
    00007FF6A70412AD  lea         rcx,[rbp*4]  
    00007FF6A70412B5  cmp         rcx,1000h  
    00007FF6A70412BC  jb          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+0D1h (07FF6A70412E1h)  
    00007FF6A70412BE  lea         rax,[rcx+27h]  
    00007FF6A70412C2  cmp         rax,rcx  
    00007FF6A70412C5  jbe         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+18Dh (07FF6A704139Dh)  
    00007FF6A70412CB  mov         rcx,rax  
    00007FF6A70412CE  call        operator new (07FF6A70416ACh)  
    00007FF6A70412D3  lea         rsi,[rax+27h]  
    00007FF6A70412D7  and         rsi,0FFFFFFFFFFFFFFE0h  
    00007FF6A70412DB  mov         qword ptr [rsi-8],rax  
    00007FF6A70412DF  jmp         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+0D9h (07FF6A70412E9h)  
    00007FF6A70412E1  call        operator new (07FF6A70416ACh)  
    00007FF6A70412E6  mov         rsi,rax  
    _Alty& _Al = this->_Getal();

    _TRY_BEGIN
    _Alty_traits::construct(_Al, _Unfancy(_Newvec + _Oldsize), _STD forward<_Valty>(_Val)...);
    00007FF6A70412E9  mov         ecx,dword ptr [r15]  
    00007FF6A70412EC  mov         dword ptr [rsi+rdi*4],ecx  
    _Emplaced = true;
    _Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
    00007FF6A70412EF  mov         rcx,rsi  
    _Emplaced = true;
    _Umove_if_noexcept(this->_Myfirst(), this->_Mylast(), _Newvec);
    00007FF6A70412F2  mov         rdx,qword ptr [rbx]  
    00007FF6A70412F5  mov         r8,qword ptr [rbx+8]  
    00007FF6A70412F9  sub         r8,rdx  
    00007FF6A70412FC  call        qword ptr [__imp_memmove (07FF6A70430B8h)]  
    _CATCH_ALL
    if (_Emplaced)
    {
    _Alty_traits::destroy(_Al, _Unfancy(_Newvec + _Oldsize));
    }

    _Al.deallocate(_Newvec, _Newcapacity);
    _RERAISE;
    _CATCH_END

    _Change_array(_Newvec, _Newsize, _Newcapacity);
    00007FF6A7041302  mov         rcx,qword ptr [rbx]  
    00007FF6A7041305  test        rcx,rcx  
    00007FF6A7041308  je          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+14Ah (07FF6A704135Ah)  
    00007FF6A704130A  mov         rdx,qword ptr [rbx+10h]  
    00007FF6A704130E  sub         rdx,rcx  
    00007FF6A7041311  sar         rdx,2  
    00007FF6A7041315  cmp         rdx,r12  
    00007FF6A7041318  ja          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+17Ah (07FF6A704138Ah)  
    00007FF6A704131A  lea         rdx,[rdx*4]  
    00007FF6A7041322  cmp         rdx,1000h  
    00007FF6A7041329  jb          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+145h (07FF6A7041355h)  
    00007FF6A704132B  lea         rax,[rdx+27h]  
    00007FF6A704132F  cmp         rax,rdx  
    00007FF6A7041332  jbe         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+17Ah (07FF6A704138Ah)  
    00007FF6A7041334  mov         rdx,rax  
    00007FF6A7041337  test        cl,1Fh  
    00007FF6A704133A  jne         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+17Ah (07FF6A704138Ah)  
    00007FF6A704133C  mov         rax,qword ptr [rcx-8]  
    00007FF6A7041340  cmp         rax,rcx  
    00007FF6A7041343  jae         std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+17Ah (07FF6A704138Ah)  
    00007FF6A7041345  sub         rcx,rax  
    00007FF6A7041348  sub         rcx,8  
    00007FF6A704134C  cmp         rcx,1Fh  
    00007FF6A7041350  ja          std::vector<int,std::allocator<int> >::emplace_back<int const & __ptr64>+17Ah (07FF6A704138Ah)  
    00007FF6A7041352  mov         rcx,rax  
    00007FF6A7041355  call        operator delete (07FF6A70416A4h)  
    00007FF6A704135A  mov         r12,qword ptr [rsp+28h]  
    00007FF6A704135F  lea         rax,[rsi+r14*4]  
    00007FF6A7041363  mov         r14,qword ptr [rsp+20h]  
    00007FF6A7041368  mov         qword ptr [rbx],rsi  
    00007FF6A704136B  mov         qword ptr [rbx+8],rax  
    00007FF6A704136F  lea         rax,[rsi+rbp*4]  
    00007FF6A7041373  mov         rsi,qword ptr [rsp+60h]  
    00007FF6A7041378  mov         rbp,qword ptr [rsp+58h]  
    00007FF6A704137D  mov         qword ptr [rbx+10h],rax  
    }

    #if _HAS_CXX17
    return (this->_Mylast()[-1]);
    #endif /* _HAS_CXX17 */
    }
    00007FF6A7041381  add         rsp,30h  

    Wednesday, January 24, 2018 8:47 PM
  • >Here is a windows console test application created with VS 2017 on Windows 10. It's built in release mode with optimizations set to /O2 (Maximize Speed).

    I'm not seeing any problem running a release (which defaults to /O2) x64 or x86 build of your example program with the latest VS2017
    15.6 Preview 2.

    Dave

    Wednesday, January 24, 2018 10:11 PM
  • First of all, thanks for testing it. Hmmm...are you using Windows 10 as the build machine? If so, please attach the generated assembly for the test program so I can compare to my configuration?

    I am currently using VS 2017 v. 15.5.1 on a Win 10 machine.

     
    Wednesday, January 24, 2018 10:23 PM
  • First of all, thanks for testing it. Hmmm...are you using Windows 10 as the build machine?

    I am, but the machine you build on makes no difference.

    I am currently using VS 2017 v. 15.5.1 on a Win 10 machine. 

    Try a later version.

    If you can still reproduce it with the latest release, place your zipped solution/project somewhere anyone can get it - such as a
    public share on onedrive.

    Dave

    Thursday, January 25, 2018 12:16 AM
  • I have VS 15.5.4. I compiled a release version so /O2 is in the command line. I also added /FAs. Is that what you want? I put it in my OneDrive. I get no exception when I execute it.


    Sam Hobbs
    SimpleSamples.Info

    Thursday, January 25, 2018 3:59 AM
  • Lo and behold, I upgraded from 15.5.3 to 15.5.4 and I am no longer seeing the offending instruction generated. I will now re-build my original application and see if the crash goes away. Thanks both of you for your assistance. This was a doozy to find. Hopefully, I will not see it again :)
    Thursday, January 25, 2018 1:26 PM
  • I think I might have spoke too soon. I need to verify a few things to ensure I'm not fooling myself. One machine, it seems to have been resolved and another not. Let me get my bearings about me, and I'll update later.
    Thursday, January 25, 2018 1:39 PM
  • I rebuilt fresh and all seems to be working. Thanks again for your instance. You can bet I'll keep an eye for this one with future updates. Something happened between 15.3.5 and 15.5.3 that caused the problem because I had another machine (Windows 7) with v. 15.3.5 and the problem was not occurring. Then when I upgraded from 15.5.3 to 15.5.4, the problem went away.
    Thursday, January 25, 2018 9:58 PM