Analyzers
Talk to fellow users of Intel Analyzer tools (Intel VTune™ Profiler, Intel Advisor)
4992 Discussions

Uninitialized memory access

Anonymous30
Beginner
1,040 Views

Hi, I am getting an uninitialized memory access error when profiling a C++ code with Inspector XE 2013. I am using 64 bit version  composer_xe_2011_sp1.7.256 to compile the code. The code shows error in line 104 of new_allocator.h.

Call stack for the error is

construct - new_allocator.h:104
push_back - stl_deque.h:1041

         I am trying to push a struct into a std::deque object. The struct is defined as follows

  struct something{

    std::vector < int > obj1;
    int obj2,obj3,obj4;
    double *obj5;
    double obj6;

//Some handles & struct specific functions

};

What is causing uninitialized memory access?

0 Kudos
9 Replies
Mark_D_Intel
Employee
1,040 Views

My guess is the top of the stack is actually in "something" (with no associated source, just disassembly?) (This is what results when I run a similar example where a member of the structure is not initialized.)

This is the compiler-generated copy constructor. IXE indicates that some member of the object pushed onto the deque is not initialized.

(Aside - you can see that it is the copy constructor by looking at the disassembly corresponding to the  "construct - new_allocator.h:104" frame  - the highlighted line is similar to "callq 0x8e < _ZN9somethingC1ERKS_ >".  Run the function name through 'c++filt', and it shows "something::something(something &const)".

If you want to know which member of 'something' is considered uninitialized, you could look at the disassembly and find the offset into the structure. Or add a copy constructor to the struct, and it should resolve to source in the IXE call stack:

[cpp]something(const something &o) {

    obj1 = o.obj1;

    obj2 = o.obj2;

    obj3 = o.obj3;

    obj4 = o.obj4;

    obj5 = o.obj5;

    obj6 = o.obj6;

}[/cpp]

0 Kudos
Anonymous30
Beginner
1,040 Views

I checked the portion which shows uninitialized memory access and that is for the pointer obj5. However, the pointer copies the intended address correctly. I am confused as to why IXE shows this error.

 

Suman
 

0 Kudos
Bernard
Valued Contributor I
1,040 Views

@suman

Are you running Windows or Linux?

0 Kudos
Peter_W_Intel
Employee
1,040 Views

@suman

You need to set element something::obj5 to NULL, since this element is a pointer. Other elements' address can be directly used (pushed) into a std::deque object.

0 Kudos
Bernard
Valued Contributor I
1,040 Views

Did you check the validity of the variable address being pointed by obj5?

0 Kudos
Mark_D_Intel
Employee
1,040 Views

How is obj5 initialized? Taking the address of an existing variable, by dynamic memory allocation, or it is one element of a dynamically allocated array?

What analysis type are you using? Detect Memory Problems (mi2 on command line) or Locate Memory Problems (mi3 on command line).  If the latter, is stack analysis on ("Analyze stack accesses" check box in the GUI - it's off by default, "-knob analyze-stack=true" on the command line) ? If stack analysis was not enabled, try the run again with it enabled.

 

 

This structure also likely has a hole in it due to alignment considerations  - 64 bit pointers (obj5) are aligned on 8-byte boundaries.  So obj1 is 24 bytes (for the example I tried), obj2,3,4 take up 12 bytes total, then the compiler will leave a 4 byte 'hole' after obj4 so that obj5 is properly aligned.  Sometimes the structure is copied by memcpy (copy all the memory contained in the structure), rather than copying it member-by-member.  There are heuristics in IXE to detect this case and avoid reporting it, so it's probably not the issue here, but I'll raise it as a possibility.

0 Kudos
Bernard
Valued Contributor I
1,040 Views

Can you resolve the address being pointed by obj5 pointer?

0 Kudos
Anonymous30
Beginner
1,040 Views

I have sorted out the problem but I want to understand the cause. So, I will try and explain my code a bit and the "work-arounds" which resulted in the error-free version.

I have a class (template) Class and have instantiated two Class's Class1 and Class2. Class 1 is say (long, double) and Class2 is say (int, double). There is also a template structure defined as

template <class INT, class DOUBLE>

struct something{

    std::vector < INT > obj1;
    INT obj2,obj3,obj4;
    DOUBLE *obj5;
    DOUBLE obj6;

//Some handles & struct specific functions

};

template <class INT, class DOUBLE>

struct another_type{

    std::vector < something<INT,DOUBLE>* > ptr1;

   std::vector < something<INT,DOUBLE>* > ptr2;

   std::vector < something<INT,DOUBLE>* > ptr3;

//Some handles & struct specific functions

};

Class1 looks something like this:

Class1{

std::vector<DOUBLE> Somedata;

std::vector<something<INT,DOUBLE>> Something1;

//Handles

Convert_to_Class2();

};

Class2 looks something like this:

Class2{

std::vector<DOUBLE> Somedata;

std::map < INT, another_type < INT, DOUBLE > > Another_Type;

std::deque <something<INT,DOUBLE>> Something2;

friend class1;

//Handles

PushToDeque(something<INT,DOUBLE>);

DoSomethingWithData();

};

Now Class1::Convert_to_Class2() copies an element of Something1 from (long, double) to (int,double) and passes it to Class2::PushToDeque function.

Then class1 calls Class2::DoSomethingWithData(). This function looks like the following:

void DoSomethingWithData(){

std::map <INT ,DOUBLE *> mymap;

      for (INT j = 0; j < ptr1.size (); j++)
        {

      for (INT i = 0; i < ptr1->obj1.size (); i++){
          if(!(mymap.count(ptr1->obj1)))
          mymap[ptr1->obj1] = ptr1->obj5 + ptr1->obj1;}

       }

      for (INT i = 0; i < ptr2->obj1.size (); i++){
          if(!(mymap.count(ptr2->obj1)))
          mymap[ptr2->obj1] = ptr2->obj5 + ptr2->obj1;}

       }

      for (INT i = 0; i < ptr3->obj1.size (); i++){
          if(!(mymap.count(ptr3->obj1)))
          mymap[ptr3->obj1] = ptr3->obj5 + ptr3->obj1;}

       }

}

When I push a pointer to mymap I get uninitialized memory error and the call stack looks something like this:

construct - new_allocator.h:104
_M_create_node - stl_tree.h:369
_M_insert - stl_tree.h:819
insert_unique - stl_tree.h:927
insert_unique - stl_tree.h:949
insert - stl_map.h:420
operator[] - stl_map.h:348
 

         If I disable mymap then the IXE error message disappears. Hope I conveyed the functioning of my code well. The question I have is why is mymap causing this error?

0 Kudos
Anonymous30
Beginner
1,040 Views

@iliyapolak Yeah, I could resolve the address issue

0 Kudos
Reply