Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

ICC 16.0.2 fails at runtime when allocating array of std::shared_ptr objects

Nicholas_S_Intel
Employee
648 Views

The Windows ICC 16.0.2 compiler (using VS2015 update 1) is failing at run time when allocating an array of shared_ptr.  The error is an Access Violation.  Meanwhile, compiling with just the msvc compiler worked.

Stepping through the code didn’t show anything obvious.  So I tried converting the raw array of shared_ptr  (*shared_ptr<T>) to a std::vector of shared_ptr (std::vector<std::shared_ptr<T>>.  I was able to move forward in execution.  But I ended up crashing later due to the same issue in another piece of code.

This is very strange, so I tried writing a trivial program that isolates the code.  Sure enough, the program crashes whenever I try to allocate an array of shared_ptr<T> (regardless of type).  See below.

Trivial Program:

#include <memory>
#include <random>

class Foo {
    int A;
    int B;
    int C[13];
};

//using MyTypeSP = Foo; //Works
//using MyTypeSP = std::shared_ptr<Foo>; //Fails, ACCESS VIOLATION
//using MyTypeSP = std::shared_ptr<int>; //Fails, ACCESS VIOLATION
//using MyTypeSP = std::vector<int>; //Works
using MyTypeSP = int; //Works

int main() {
    const int count = rand() % 50;
    MyTypeSP *m_pMCIDs;
    m_pMCIDs = new MyTypeSP[count];

    return 0;
}

Can anybody else repeat this behavior?

0 Kudos
9 Replies
Nicholas_S_Intel
Employee
648 Views

Some additional info... I tested this using the Linux Intel Compiler (16.0.2 with gcc 5.2.0), and it works.  

I also have some more examples.  It seems to break when trying to allocate a dynamically sized array (see last case)

#include <memory>
#include <random>
int main()
{
    using MyTypeSP = std::shared_ptr<int>;  

    new MyTypeSP; //Works
    new MyTypeSP[1]; //Works
    new MyTypeSP[50]; //Works

    const int cCount = 50;
    new MyTypeSP[cCount]; // Works

    int count = rand() % 50;
    new MyTypeSP[count]; //Fails, ACCESS VIOLATION
    return 0;
}

 

 

0 Kudos
Melanie_B_Intel
Employee
648 Views

I compiled this with Intel 16.0 update 2 and vs2015 update 1 it executes without problem. This is with 

Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64

I used iclvars.bat intel64 vs2015 to configure my environment

M:\>icl share.cpp
Intel(R) C++ Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 16.0.2.180 Build 20160204
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.

share.cpp
Microsoft (R) Incremental Linker Version 14.00.23506.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:share.exe
share.obj

M:\>.\share.exe

M:\>type share.cpp
#include <memory>
#include <random>
int main()
{
    using MyTypeSP = std::shared_ptr<int>;

    new MyTypeSP; //Works
    new MyTypeSP[1]; //Works
    new MyTypeSP[50]; //Works

    const int cCount = 50;
    new MyTypeSP[cCount]; // Works

    int count = rand() % 50;
    new MyTypeSP[count]; //Fails, ACCESS VIOLATION
    return 0;
}

I also tried your "trivial" program with the 2 different definitions using shared_ptr and program execution didn't fail with Intel compiler. 

Did you build with different options? Were you using the intel64 compiler?

0 Kudos
Nicholas_S_Intel
Employee
648 Views

Hi Melanie,

I executed the same steps you took (via command line) and the program ran successfully.  It seems to fail only within visual studio..

Here are the steps I took:

  1. Create a Project C++/Empty Project
  2. Add .cpp file, and paste in my trivial example
  3. Right click on Project/ use intel c++
  4. With Debug/x86 configuration, I build and execute the program.
  5. Program crashes with Access Violation.

Here are the C++ Compiler arguments:

/GS /W3 /Zc:wchar_t /ZI /Od /Fd"Debug\vc140.pdb" /D "_MBCS" /Zc:forScope /RTC1 /Gd /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Qprof-dir "Debug\" /Fp"Debug\Project1.pch" 

 And the Linker Arguments:

/OUT:"c:\users\nschultz\documents\visual studio 2015\Projects\Project1\Debug\Project1.exe" /MANIFEST /NXCOMPAT /PDB:"c:\users\nschultz\documents\visual studio 2015\Projects\Project1\Debug\Project1.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG:FASTLINK /MACHINE:X86 /INCREMENTAL /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\Project1.exe.intermediate.manifest" /NOLOGO /TLBID:1

 

0 Kudos
Nicholas_S_Intel
Employee
648 Views

Melanie, 

Optimization is enabled by default, which removed all the statements in the trivial application.

can you try compiling with '/Od' ?

 

>icl Source.cpp /Od

Intel(R) C++ Intel(R) 64 Compiler for applications running on IA-32, Version 16.
0.2.180 Build 20160204
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.

Source.cpp
Microsoft (R) Incremental Linker Version 14.00.23506.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:Source.exe
Source.obj

>Source.exe
passing...
about to fail

(ACCESS VIOLATION)

>type Source.cpp

#include <memory>
#include <random>

int main()
{
    using MyTypeSP = std::shared_ptr<int>;
    printf("passing...\n");
    new MyTypeSP; //Works
    new MyTypeSP[1]; //Works
    new MyTypeSP[50]; //Works

    const int cCount = 50;
    new MyTypeSP[cCount]; // Works

    printf("about to fail\n");
    int count = rand() % 50;
    new MyTypeSP[count]; //Fails, ACCESS VIOLATION

    return 0;
}

 

 

0 Kudos
Nicholas_S_Intel
Employee
648 Views

following code should produce an error with optimizations enabled/disabled with ICC 16.0.2.  msvc compiler works as expected.

 

#include <memory>
#include <random>

int main()
{
    using MyTypeSP = std::shared_ptr<int>;

    printf("passing...\n");
    new MyTypeSP; //Works
    new MyTypeSP[1]; //Works
    new MyTypeSP[50]; //Works

    const int cCount = 50;
    new MyTypeSP[cCount]; // Works

    printf("about to fail\n");
    int count = rand() % 50;
    auto myArray =  new MyTypeSP[count]; //Fails: ACCESS VIOLATION (fails only in DEBUG mode, RELEASE OK)
    
    for (int i = 0; i < rand() % 10000; i++)
    {
        int index = rand() % count;
        printf("setting to null");
        myArray[index] = MyTypeSP(nullptr); //Fails: ACCESS VIOLATION (ICC RELEASE mode)
        printf("iteration: %0.3d, idx: %0.3d, addr: %p, sp: %p\n", i, index, &myArray[index], myArray[index].get());         
    }
    return 0;
}

 

0 Kudos
Bernard
Valued Contributor I
648 Views

NICHOLAS S. (Intel) wrote:

Some additional info... I tested this using the Linux Intel Compiler (16.0.2 with gcc 5.2.0), and it works.  

I also have some more examples.  It seems to break when trying to allocate a dynamically sized array (see last case)

#include <memory>
#include <random>
int main()
{
    using MyTypeSP = std::shared_ptr<int>;  

    new MyTypeSP; //Works
    new MyTypeSP[1]; //Works
    new MyTypeSP[50]; //Works

    const int cCount = 50;
    new MyTypeSP[cCount]; // Works

    int count = rand() % 50;
    new MyTypeSP[count]; //Fails, ACCESS VIOLATION
    return 0;
}

 

 

Nicholas did you try to put breakpoint on "count" variable and inspect its content? Maybe this is the culprit of the access violation?

0 Kudos
Melanie_B_Intel
Employee
648 Views

Ok yes, with /Od I can see it now. I opened DPD200407977 in our internal bugs database. Thank you for reporting this problem.

0 Kudos
Nicholas_S_Intel
Employee
648 Views

iliyapolak wrote:

Nicholas did you try to put breakpoint on "count" variable and inspect its content? Maybe this is the culprit of the access violation?

yes, count is a reasonable value between 0 and 49.

0 Kudos
Bernard
Valued Contributor I
648 Views

I do not know if it will help to solve your problem, but anyway can you post the disassembly of the failed code?

0 Kudos
Reply