How to catch error : The memory could not be read.

Hi all,

I am experiencing this error: The instruction at '' referenced memory at ''. The memory could not be read. What I want to do is possibly Catch that error and execute a Go To Statement so that it will skip that part of the code altogether.

I do not know what parameter to put in the catch(<?>) block. Can anyone help me with this? Is it also possible if I want the code part where I want to GoTo is located in a different class/file?


Some additional information: This error occurs when I try to read an XML node attribute but is not present. Here is the part of the code where I think it causes this error.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
VARIANT GetAttribute(string attribute, IXMLDOMNamedNodeMap* pNodeMap)
{
	VARIANT varAtt;

	IXMLDOMNode* pAtt = NULL;

	_bstr_t tempb = attribute.c_str();
	//Process varSource first to determine if to use WMI or TSVar
	BSTR bstrAtt = tempb.copy();
	pNodeMap->getNamedItem(bstrAtt,&pAtt);
	pAtt->get_nodeValue(&varAtt);

	SAFE_RELEASE(pAtt);

	return varAtt;
}



Thank you!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
VARIANT GetAttribute(string attribute, IXMLDOMNamedNodeMap* pNodeMap)
{
	VARIANT varAtt;

	IXMLDOMNode* pAtt = NULL;

	_bstr_t tempb = attribute.c_str();
	//Process varSource first to determine if to use WMI or TSVar
	BSTR bstrAtt = tempb.copy();

        if (pNodeMap != NULL)
        {
	        pNodeMap->getNamedItem(bstrAtt,&pAtt);
                if (pAtt != NULL)
                {
                     pAtt->get_nodeValue(&varAtt);
                     SAFE_RELEASE(pAtt);
                }
        }	

	return varAtt;
}
The instruction at '' referenced memory at ''. The memory could not be read.

That doesn't sound like an exception - more like a segfault.

Not all problems in C++ can be catched using exception handling. If you experience a null-pointer access here, for example in line 10 when you access pNodeMap which is 0, then you can't catch this error in C++. You have to fix the code.

You can either make extra-sure you don't pass 0 ever and fix the place where 0 gets passed. Or maybe better: Check for 0 within GetAttribute and do some defined actions in this case (e.g. throw an exception, return a NULL-variant or whatever..)

1
2
3
4
5
6
VARIANT GetAttribute(string attribute, IXMLDOMNamedNodeMap* pNodeMap)
{
    if (pNodeMap == 0)
        throw std::logic_error("Someone passed 0 as pNodeMap. This should not happen");
...
}



Now for your original question: From the catch-block, it's not directly possible to know at which statement in a try-block the excaption occurs.

1
2
3
4
5
6
7
8
try {
    do_something_that_might_raise_exceptions();
    do_something_else_that_might_also_raise_exceptions();
}
catch(...)
{
    // you have no way of knowing here whether the first or second function raised the exception.
}


You could use variables to remember what statement suceeded or you could split the try/catch into numerous smaller ones. Both solutions are ugly. ;)

Ciao, Imi.
Hi all, thank you for replying.

@Denis: Thank you for that code. I am using it now and it helped me reduce the error. Although I still experience a memory error. Do you know how to check if a VARIANT data type is NULL or has no value? I mean if it was not assigned to (for example, the attribute is missing), how can I check that the function has failed? I tried something like if(varAtt == NULL) but it produces a compile error.

@imi: Thank you for replying. It provided me with nice insight. Do you by any chance know an answer to what I asked Denis?

Thank you very much!
Actually I don't know which methods VARIANT type has
Hi all,

@Denis: Ok thank you.

By the way, here is the solution how to find out if VARIANT is empty. Just want to share:

Hello Lean A,

1. >> Do you know how to check if a VARIANT data type is NULL or has no value?

1.1 One way to do this would be to check to see if the VARTYPE is VT_EMPTY.

For example :

pAtt->get_nodeValue(&varAtt);

if (V_VT(&varAtt) == VT_EMPTY)
{
...
}

1.2 But this assumes that the method will initialize the out parameter "varAtt" via VariantInit() before returning.

1.3 To ensure that "varAtt" is set to a proper value, it is best to call VariantInit() on "varAtt" before calling the method. E.g. :

VariantInit(&varAtt);
pAtt->get_nodeValue(&varAtt);

1.4 The return HRESULT may also be useful in determining success/failure.

1.5 Consult the documentation to be sure.

- Bio.

Thank you all!
Yea.. VARIANT is not part of the standard lib.

I got the feeling, that this forum here is great for answering questions about the standard libs and the standard language features in general (e.g. everything that starts with "std::" or where you include some file without any extension like "iostream" ;-)

But it's not optimal for specific third party libs. (For common and portable libs like from boost.org or Loki, you may get information here too).


A note about Denis' code: It should work just fine, but if you using exception handling in your program anyway, I would probably do it a bit differently:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
VARIANT GetAttribute(string attribute, IXMLDOMNamedNodeMap* pNodeMap)
{
	if (pNodeMap == 0)
		throw std::logic_error("called GetAttribute without an xml-element");

	VARIANT varAtt;

	IXMLDOMNode* pAtt = NULL;

	_bstr_t tempb = attribute.c_str();
	//Process varSource first to determine if to use WMI or TSVar
	BSTR bstrAtt = tempb.copy();

	pNodeMap->getNamedItem(bstrAtt, &pAtt);
	if (pAtt)
	{
		pAtt->get_nodeValue(&varAtt);
		SAFE_RELEASE(pAtt);
	}

	return varAtt;
}


It seems to me, that some user of GetAttribute should check for the existance of the whole XML element, before he tries to read an attribute for it. It's ok to try to read a non-existing attribute (which returns your VT_EMPTY. Quite sound interface). But any check to non-existing XML-elements seem not to belong into this function IMHO.

(Some prefer to replace the "if (pNodeMap..." lines with an "assert".)


But in the end, as I said: Denis' version does gets the job done too. :)

Ciao, Imi.
Topic archived. No new replies allowed.