Error when using the delete array operator on a CDBVariant array

Viewed 107

I create, use, and delete an array of CDBVariant :

CDBVariant *myVars = new CDBVariant[N];
// ...
delete[] myVars;

On the delete[] line the execution meets 3 breakpoints I can't explore, then Access Violations in reading over and over until it crashes. I have the exact same symptoms as this guy : http://computer-programming-forum.com/82-mfc/549a933737d9177d.htm ; namely I can use new[]/delete[] on other object types with no problem, and I can wrap the CDBVariant in a useless class and create/delete arrays of this class.

This happens specifically while using MFC. If I create a new console app and launch this;

#include <cassert>
#include <afxdb.h>
int main(void)
{
    CDBVariant *vars = new CDBVariant[10];
    assert(vars[0].m_dwType == DBVT_NULL); // don't optimise my array away please.
    delete[] vars;
}

it wont cause any trouble. If, however, I create a basic, default MFC app (dialog-based, 'cause that's what I use) and use the OK button of the default dialog to do the same thing;

void CMFCApplication1Dlg::OnBnClickedOk()
{
    CDBVariant *vars = new CDBVariant[10];
    assert(vars[0].m_dwType == DBVT_NULL);
    delete[] vars;
    
    CDialogEx::OnOK();
}

once again, breaks, then access violations, then death. (I use VS2017 with MSVC 19.10.25027.)

Please tell me what causes this, and how to properly avoid it.

Here are the requested disassembly codes. Sorry for the heaviness. Here is the console version:

    delete[] vars;
00558E6D  mov         eax,dword ptr [vars]  
00558E70  mov         dword ptr [ebp-110h],eax  
00558E76  mov         ecx,dword ptr [ebp-110h]  
00558E7C  mov         dword ptr [ebp-104h],ecx  
00558E82  mov         edx,dword ptr [ebp-104h]  
00558E88  mov         dword ptr [ebp-0F8h],edx  
00558E8E  cmp         dword ptr [ebp-0F8h],0  
00558E95  je          main+172h (0558EF2h)  
00558E97  mov         eax,dword ptr [ebp-0F8h]  
00558E9D  cmp         dword ptr [eax-4],0  
00558EA1  je          main+148h (0558EC8h)  
00558EA3  mov         esi,esp  
00558EA5  push        3  
00558EA7  mov         ecx,dword ptr [ebp-104h]  
00558EAD  mov         edx,dword ptr [ecx]  
00558EAF  mov         ecx,dword ptr [ebp-104h]  
    delete[] vars;
00558EB5  mov         eax,dword ptr [edx]  
00558EB7  call        eax  
00558EB9  cmp         esi,esp  
00558EBB  call        __RTC_CheckEsp (0515C33h)  
00558EC0  mov         dword ptr [ebp-118h],eax  
00558EC6  jmp         main+164h (0558EE4h)  
00558EC8  mov         ecx,dword ptr [ebp-0F8h]  
00558ECE  sub         ecx,4  
00558ED1  push        ecx  
00558ED2  call        operator delete[] (052763Bh)  
00558ED7  add         esp,4  
00558EDA  mov         dword ptr [ebp-118h],0  
00558EE4  mov         edx,dword ptr [ebp-118h]  
00558EEA  mov         dword ptr [ebp-11Ch],edx  
00558EF0  jmp         main+17Ch (0558EFCh)  
00558EF2  mov         dword ptr [ebp-11Ch],0  

The call eax line leads to

CDBVariant::`vector deleting destructor':
0051EC84  jmp         CDBVariant::`vector deleting destructor' (0556E30h)  

which immediately jumps away to a big block of code, introduced as CDBVariant::`vector deleting destructor'.

The MFC version looks very similar at first:

delete[] vars;
00FB7D0A  mov         eax,dword ptr [vars]  
00FB7D0D  mov         dword ptr [ebp-11Ch],eax  
00FB7D13  mov         ecx,dword ptr [ebp-11Ch]  
00FB7D19  mov         dword ptr [ebp-110h],ecx  
00FB7D1F  mov         edx,dword ptr [ebp-110h]  
00FB7D25  mov         dword ptr [ebp-104h],edx  
00FB7D2B  cmp         dword ptr [ebp-104h],0  
00FB7D32  je          CMFCApplication1Dlg::OnBnClickedOk+18Fh (0FB7D8Fh)  
00FB7D34  mov         eax,dword ptr [ebp-104h]  
00FB7D3A  cmp         dword ptr [eax-4],0  
00FB7D3E  je          CMFCApplication1Dlg::OnBnClickedOk+165h (0FB7D65h)  
00FB7D40  mov         esi,esp  
00FB7D42  push        3  
00FB7D44  mov         ecx,dword ptr [ebp-110h]  
00FB7D4A  mov         edx,dword ptr [ecx]  
00FB7D4C  mov         ecx,dword ptr [ebp-110h]  
00FB7D52  mov         eax,dword ptr [edx]  
00FB7D54  call        eax  
00FB7D56  cmp         esi,esp  
00FB7D58  call        __RTC_CheckEsp (0FB1474h)  
00FB7D5D  mov         dword ptr [ebp-124h],eax  
00FB7D63  jmp         CMFCApplication1Dlg::OnBnClickedOk+181h (0FB7D81h)  
00FB7D65  mov         ecx,dword ptr [ebp-104h]  
00FB7D6B  sub         ecx,4  
00FB7D6E  push        ecx  
00FB7D6F  call        operator delete[] (0FB1B4Fh)  
00FB7D74  add         esp,4  
00FB7D77  mov         dword ptr [ebp-124h],0  
00FB7D81  mov         edx,dword ptr [ebp-124h]  
00FB7D87  mov         dword ptr [ebp-128h],edx  
00FB7D8D  jmp         CMFCApplication1Dlg::OnBnClickedOk+199h (0FB7D99h)  
00FB7D8F  mov         dword ptr [ebp-128h],0  

but its call eax goes here:

0FCF7810  push        ebp  
0FCF7811  mov         ebp,esp  
0FCF7813  push        ecx  
0FCF7814  mov         dword ptr [ebp-4],0CCCCCCCCh  
0FCF781B  mov         dword ptr [ebp-4],ecx  
0FCF781E  mov         ecx,dword ptr [ebp-4]  
0FCF7821  call        0FCF77B0  
0FCF7826  mov         eax,dword ptr [ebp+8]  
0FCF7829  and         eax,1  
0FCF782C  je          0FCF783C  
0FCF782E  push        18h  
0FCF7830  mov         ecx,dword ptr [ebp-4]  
0FCF7833  push        ecx  
0FCF7834  call        0FE87AB0  
0FCF7839  add         esp,8  
0FCF783C  mov         eax,dword ptr [ebp-4]  
0FCF783F  add         esp,4  
0FCF7842  cmp         ebp,esp  
0FCF7844  call        0FE879E0  
0FCF7849  mov         esp,ebp  
0FCF784B  pop         ebp  
0FCF784C  ret         4  

The first break happens here:

ntdll.dll!770e48c2() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!770843d7() Unknown
KernelBase.dll!73bf4814() Unknown
ucrtbased.dll!0fdf611b() Unknown
ucrtbased.dll!0fdf4a0e() Unknown
ucrtbased.dll!0fdf75bc() Unknown
mfc140ud.dll!0f641372() Unknown
mfc140ud.dll!0fa97abc() Unknown
mfc140ud.dll!0f907839() Unknown
MFCApplication1.exe!CMFCApplication1Dlg::OnBnClickedOk() Line 96 C++

the second and third a bit higher:

ucrtbased.dll!0fdf4a3a() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ucrtbased.dll]
ucrtbased.dll!0fdf75bc() Unknown
mfc140ud.dll!0f641372() Unknown
mfc140ud.dll!0fa97abc() Unknown
mfc140ud.dll!0f907839() Unknown
MFCApplication1.exe!CMFCApplication1Dlg::OnBnClickedOk() Line 96 C++

and finally the call stack gets lost and the execution loops sending exceptions from there:

ucrtbased.dll!0fe55f0c() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ucrtbased.dll]
ucrtbased.dll!0fe563d1() Unknown
ucrtbased.dll!0fe55dcb() Unknown
ucrtbased.dll!0fe56d02() Unknown
ucrtbased.dll!0fe468a9() Unknown
ucrtbased.dll!0fe464bf() Unknown
ucrtbased.dll!0fe3d8a2() Unknown
ucrtbased.dll!0fe37319() Unknown
ucrtbased.dll!0fe2f545() Unknown
ucrtbased.dll!0fdface6() Unknown
ucrtbased.dll!0fdfa17b() Unknown
ucrtbased.dll!0fdf8043() Unknown

"0xC0000005: Access violation reading location 0x00000047."

0 Answers
Related