Certain functions in my program get a bad pointer with a low probability.
The pointer is the CComPtr <IHTMLDocument2> m_htmldocument2 variable.
Moving the m_htmldocument2 variable to a local variable causes an access violation error if m_htmldocument2 is not a valid value.
I did not have a way to check if m_htmldocument2 was a valid value, and tried to process it as __try __except, but I could not do it because there was a destructor.
Is there a safe way to move to a local variables?
Related
I'm using the gsl library in C++. I have declared a gsl_vector pointer mesh as a private member of the class.
private:
gsl_vector * mesh;
I also have a method, MeshBuilder, that declares a gsl_vector, pointer mesh (over-riding the original mesh variable) and returns mesh.
gsl_vector * ThinFilm::LinearMesh(...){
gsl_vector * mesh = gsl_vector_alloc(numberofcells);
...
return mesh;
}
I then assign the result of the method to the variable mesh as:
mesh = MeshBuilder(...);
It compiles and runs just fine (no warnings either, with -Wall). Stepping through the program I noticed that the variable mesh is assigned an address, and then the MeshBuilder overwrites that. Which is exactly what I programmed to do.
But is it good practice? After all, shouldn't I not assign a value to the pointer address?
Shouldn't I instead not declare a the mesh pointer in the MeshBuilder method and therefore directly use the pointer declared in the private section of the class?
I'm guessing the only reason this works is because the address value I'm assigning to mesh is in fact valid having been declared.
The mesh variable in the method shadows the private's variable.
If you use the private variable directly, then you avoid declaring a temporary, but in practice, it does not change much.
However, if the interface of the class is to be used in multithreaded contexts, then changing the private variable directly will make it visible to any other thread at the allocation time, so if the ... section in the code above does some sort of setup of the vector, it means other thread might see or use an invalid (not constructed) variable.
In that case, you should use a temporary (like in your initial code) and protect the assignment mesh = MeshBuilder(...) with either a mutex or an atomic operation (like CAS, or pointer exchange).
Also, in all cases, if you want to write safe code, you should also consider what is going to happen is an exception is thrown in the ... part of the code.
Setting the private variable directly, you might have a chance to clean the allocation (in the destructor of your class), else you'll get a memory leak since a pointer does not clean the allocation by itself.
If you want a really safe code that's working in all possible conditions, you should use a smart pointer in place of the temporary (for exception safe code), a mutex to protect private variable access (for multithread safe code).
Simple answer is no, in your current code, you are leaking a resource.
The problem is gsl_vector_alloc does not return a value, but indeed an address, which point to a struct that contain the value you except to see. In this context, gsl_vector_alloc is behaving similar to using new, as it allocating a vector struct, and initializing it.
The function gsl_vector_alloc, as it name suggest allocate a vector. This mean you need to free it with gsl_vector_free before you are overriding it.
Also allocation can fail, in such a case gsl_vector_alloc will return NULL and you will have to check for it, before using mesh.
Side note: In the function you are providing you call your local variable mesh, which has the same name as a private member, this is a bad practice as the local variable will hide the private member.
I've created a class, say I named it MyClass, as well as another that inherits from it, say MyClassDaughter then I tried the following:
MyClassDaughter *MyClassDaughterPointer;
vector <MyClass*> MyClassVector;
MyClassVector.push_back(MyClassDaughterPointer);
MyClassVector[0]->SetSomethingInMyClassDaughter;
When I try to run the executable it says "Segmentation Violation".
(I think must say that my code has some Root stuff in it... Could that be the problem? Anyways, I know that, usually, segmentation violation errors are cause by trying to access memory that we don't have permission to access, but I think I do have permission to access this memory. Am I wrong?)
You do not initialize MyClassDaughterPointer, so you push some random (wild) pointer to the vector.
You need to create new instance of MyClassDaughterPointer. Assuming you have a default constructor, it will look like this:
MyClassDaughter *MyClassDaughterPointer = new MyClassDaughterPointer();
The pointer
MyClassDaughter *MyClassDaughterPointer;
Was never set to anything but there is some uninitialized content if that was on the stack or just null is that was static. Therefore you cannot try to access it as you do, that causes Undefined Behavior.
MyClassVector[0]->SetSomethingInMyClassDaughter; // that is same pointer set in vector entry
Unsure what compiler does as long as it usually has such code to be optimized out and that should not have any effect - no job for CPU here at all as long as that pointer is not used. But debug mode is right always attempting to load the address to some register.
What is the behavior of calling a null function pointer?
void (*pFunc)(void) = NULL;
pFunc();
Why is it advisable to initialize yet unused function pointers to NULL?
In C and C++, this is called undefined behaviour, meaning that this can lead to a Segmentation fault, nothing or whatever such a case will cause based on your compiler, the operating system you're running this code on, the environment (etc...) means.
Initializing a pointer to a function, or a pointer in general to NULL helps some developers to make sure their pointer is uninitialized and not equal to a random value, thereby preventing them of dereferencing it by accident.
What happnes when u try to access NULL?
Following is true about data as well as code, and this is what
happens when you try to read NULL(or any address from 0 to
4096,i.e atleast first page of segment). Root cause of this lies in
OS and microprocessor segmentation/paging architecture
When you try to access NULL( or 0) address, in any of data or code
section, it causes segmentation fault(which is actually a killer
page fault). First page of section is treated as out of( or invalid
part of) virtual address space. That is purposefully that first page
is kept invalid( or not present) so atleast one address that pointer
contains could be represented as invalid in program at execution
time.
Page descriptor of the 1st page(which contains virtual address 0,
NULL), has first bit "present" as 0 (means its invalid page). Now if
you try to access NULL pointer(0 address) it will cause to raise a
page fault as page is not present, and OS will try to handle this
page fault. When page fault handler see that its trying to access
1st page, which is treated as a invalid part of virtual address
space it kills the process. This is all about user space process. If
you try to access NULL pointer in system process(kernel level code),
it will fail your OS an crash the system.
Links: http://en.wikipedia.org/wiki/Page_fault#Invalid
http://en.wikipedia.org/wiki/Memory_protection#Paged_virtual_memory
http://pdos.csail.mit.edu/6.828/2005/readings/i386/s05_02.htm
Above is sufficient bt as i think u should read this as well
http://www.iecc.com/linker/linker04.txt
Why function pointer is initialized to NULL?
Although if you try to call the with NULL its going to give page/segment fault. NULL signifies its invalid function. If it
contains any garbage address but in valid virtual address space of
code section, i think any code at that address will be called, which
could be even more disaster(spl in case of real time systems).
Initialize funcp = funct_foo_name + 1; now call function using
function pointer. Function pointer points to valid virtual address
space of code section. bt function will start from incorrect place
to execute. which could result into wrong code execution or wrong
order.
It's advisable for the same reason as initializating "normal" (data) pointers to NULL: because it potentially makes some errors easier to track down. Opinions on whether this is useful or not of course vary :-)
While browsing open source code (from OpenCV), I came across the following type of code inside a method:
// copy class member to local variable for optimization
int foo = _foo; //where _foo is a class member
for (...) //a heavy loop that makes use of foo
From another question on SO I've concluded that the answer to whether or not this actually needs to be done or is done automatically by the compiler may be compiler/setting dependent.
My question is if it would make any difference if _foo were a static class member? Would there still be a point in this manual optimization, or is accessing a static class member no more 'expensive' than accessing a local variable?
P.S. - I'm asking out of curiosity, not to solve a specific problem.
Accessing a property means de-referencing the object, in order to access it.
As the property may change during the execution (read threads), the compiler will read the value from memory each time the value is accessed.
Using a local variable will allow the compiler to use a register for the value, as it can safely assume the value won't change from the outside. This way, the value is read only once from memory.
About your question concerning the static member, it's the same, as it can also be changed by another thread, for instance. The compiler will also need to read the value each time from memory.
I think a local variable is more likely to participate in some optimization, precisely because it is local to the function: this fact can be used by the compiler, for example if it sees that nobody modifies the local variable, then the compiler may load it once, and use it in every iteration.
In case of member data, the compiler may have to work more to conclude that nobody modifies the member. Think about multi-threaded application, and note that the memory model in C++11 is multi-threaded, which means some other thread might modify the member, so the compiler may not conclude that nobody modifies it, in consequence it has to emit code for load member for every expression which uses it, possibly multiple times in a single iteration, in order to work with the updated value of the member.
In this example the the _foo will be copied into new local variable. so both cases the same.
Statis values are like any other variable. its just stored in different memory segment dedicated for static memory.
Reading a static class member is effectively like reading a global variable. They both have a fixed address. Reading a non-static one means first reading the this-pointer, adding an offset to the result and then reading that address. In other words, reading a non-static one requires more steps and memory accesses.
Unhandled exception at 0x523d14cf (msvcr100d.dll) in IntellitracTCPIP.exe: 0xC0000005: Access violation reading location 0x00000008.
what can cause this error? and how to solve it
The address you're attempting to read suggests that you have a struct consisting of a number of 4-byte integers. You have a pointer to that struct type, but that pointer is null. Your program wants to read the third one — the offset of the third integer field would be 8. Add that to the null-pointer address 0, and you get 0x00000008. (It could be a struct of smaller or larger types, or even an array, but my experience tells me 4-byte integers is most likely.)
The error message indicates that the offending line of code belongs to msvcr100d.dll. That's not your code; you have probably passed a null pointer to some C run-time function. That function has assumed you provided a valid pointer and attempted to read the third field of the struct, but since that pointer is not valid, the OS intercepted the read attempt and threw an exception instead.
Find the last line of code in your program before that error occurs. To do that, you can use the call stack to see the chain of function calls that your program made to get to the point it crashed. Go down the list until you find one of your functions. Do you see any pointers? Can you guarantee that they're all valid when you call that function? If not, then are you sure you're supposed to call that function? Either make sure the pointer is valid, or avoid calling the function with null pointers.
0xC0000005: Access violation reading location 0x00000008.
This indicate a bad pointer. No pointers show point to such a low address as 0x00000008. You are not giving enough information on this, try running the program under a debugger.