Invalid Address specified to RtlValidateHeap in EXE Server 
Author Message
 Invalid Address specified to RtlValidateHeap in EXE Server

Hi:

   I'm passing a BSTR (also tried passing a BSTR*) that must be converted to
an LPCTSTR. I got the conversion code from  the MSDN sample "Implementing a
Simple MFC Client for an ATL Server". It seems to work OK. At least it
compiles and doesn't complain on run-time.
   However, at the end of the method, after returning 0L, I get:

    HEAP[MyApp.exe]: Invalid Address specified to RtlValidateHeap( 340000,
12f814 )

   I suppose it has something to do with string clean up, LPCTSTR conversion
or something like that, but I can't make it out. Could you, please, help me?

STDMETHODIMP CIRServer::NewJob(/*[in]*/ BSTR* JobName, /*[out,
retval]*/VARIANT* pVariant)
{
// LPCTSTR name;

 USES_CONVERSION;
//Update static text with new value
 unsigned cmb;

 if(JobName)
      cmb= wcstombs(NULL, JobName, SysStringLen(JobName)) + 1;
 else
      cmb= 1;

// name = W2CT(JobName);
 //_bstr_t name(JobName, FALSE); //necessary to avoid a memory leak

ImpJob* pJob = CreateJob (W2CT(JobName));

 VariantInit (pVariant);
 pVariant->vt = VT_BYREF|VT_VARIANT;

 SAFEARRAY* psa = NULL;
 SAFEARRAYBOUND bound  = {1, 0};

 psa = SafeArrayCreate (VT_VARIANT, 1, &bound);
 if (psa == NULL)
      return E_OUTOFMEMORY;

 long i=0;
 SafeArrayPutElement (psa, &i, &pJob);

 pVariant->parray = psa;

 return 0L;

Quote:
}

    If I use _bstr_t name(JobName, FALSE), I get:
        error C2040: 'name' : 'class _bstr_t' differs in levels of
indirection from 'const char *'

    So, is it the conversion, the VARIANT*, or what?

    Thanks a lot.
    Best wishes. Javier.



Tue, 09 Sep 2003 21:10:17 GMT  
 Invalid Address specified to RtlValidateHeap in EXE Server
I assume JobName is BSTR after all, not BSTR*, otherwise the code won't even
compile.

Your problem is you lie about your variant type. You put the type of
VT_VARIANT | VT_BYREF, then store a SAFEARRRAY in it, which should have been
VT_VARIANT | VT_ARRAY. It is unclear to me if it is even allowed to return
VT_VARIANT | VT_BYREF as a pure [out] parameter, as I can't find it
documented anywhere how a nested variant is supposed to be allocated and
freed. I guess it is usable only as an [in, out] parameter.

--
With best wishes,
    Igor Tandetnik


Quote:
> Hi:

>    I'm passing a BSTR (also tried passing a BSTR*) that must be converted
to
> an LPCTSTR. I got the conversion code from  the MSDN sample "Implementing
a
> Simple MFC Client for an ATL Server". It seems to work OK. At least it
> compiles and doesn't complain on run-time.
>    However, at the end of the method, after returning 0L, I get:

>     HEAP[MyApp.exe]: Invalid Address specified to RtlValidateHeap( 340000,
> 12f814 )

>    I suppose it has something to do with string clean up, LPCTSTR
conversion
> or something like that, but I can't make it out. Could you, please, help
me?

> STDMETHODIMP CIRServer::NewJob(/*[in]*/ BSTR* JobName, /*[out,
> retval]*/VARIANT* pVariant)
> {
> // LPCTSTR name;

>  USES_CONVERSION;
> file://Update static text with new value
>  unsigned cmb;

>  if(JobName)
>       cmb= wcstombs(NULL, JobName, SysStringLen(JobName)) + 1;
>  else
>       cmb= 1;

> // name = W2CT(JobName);
>  file://_bstr_t name(JobName, FALSE); file://necessary to avoid a memory
leak

> ImpJob* pJob = CreateJob (W2CT(JobName));

>  VariantInit (pVariant);
>  pVariant->vt = VT_BYREF|VT_VARIANT;

>  SAFEARRAY* psa = NULL;
>  SAFEARRAYBOUND bound  = {1, 0};

>  psa = SafeArrayCreate (VT_VARIANT, 1, &bound);
>  if (psa == NULL)
>       return E_OUTOFMEMORY;

>  long i=0;
>  SafeArrayPutElement (psa, &i, &pJob);

>  pVariant->parray = psa;

>  return 0L;
> }

>     If I use _bstr_t name(JobName, FALSE), I get:
>         error C2040: 'name' : 'class _bstr_t' differs in levels of
> indirection from 'const char *'

>     So, is it the conversion, the VARIANT*, or what?

>     Thanks a lot.
>     Best wishes. Javier.



Tue, 09 Sep 2003 22:53:13 GMT  
 Invalid Address specified to RtlValidateHeap in EXE Server

    Thanks a lot, it works now (and yes, it was BSTR, not BSTR*). But I
still have a problem with the safearray.

STDMETHODIMP CIRServer::NewJob(BSTR name, VARIANT* pVariant)
{
 IImpJob* pJob = CreateJob(name);

 VariantInit (pVariant);
 pVariant->vt = VT_ARRAY|VT_VARIANT;

 SAFEARRAY* psa = NULL;
 SAFEARRAYBOUND bound  = {1, 0};

 psa = SafeArrayCreate (VT_VARIANT, 1, &bound);
 if (psa == NULL)
     return E_OUTOFMEMORY;

 long i=0;
 HRESULT hr = SafeArrayPutElement (psa, &i, &pJob);
 pVariant->parray = psa;

 return 0L;

Quote:
}

    SafeArrayPutElement returns 80020008 (Bad Variable Type). Doesn't it
accept my IImpJob*?

   Thanks before hand.
   Best wishes. Javier.

------------------



Quote:
> I assume JobName is BSTR after all, not BSTR*, otherwise the code won't
even
> compile.

> Your problem is you lie about your variant type. You put the type of
> VT_VARIANT | VT_BYREF, then store a SAFEARRRAY in it, which should have
been
> VT_VARIANT | VT_ARRAY.



Wed, 10 Sep 2003 01:39:53 GMT  
 Invalid Address specified to RtlValidateHeap in EXE Server
You create safearray of variants, so SafeArrayPutElement naturally expects a
pointer to a variant as the last parameter. You supply it with garbage. I
guess it checks first byte of what this garbage points to (would have been
vt if it were a variant), sees that it is not a valid type specification
(you are lucky it isn't) and reports an error. Had the first byte
accidentally contained something valid as vt, you'd get a crash on your
hands.

You should do

VARIANT v;
V_VT(&v) = VT_UNKNOWN; // or VT_DISPATCH if IImpJob is disp- or dual
interface
V_UNKNOWN(&v) = pJob;
HRESULT hr = SafeArrayPutElement (psa, &i, &v);
// Don't call VariantClear(&v) since we didn't AddRef when filling v

--
With best wishes,
    Igor Tandetnik


Quote:

>     Thanks a lot, it works now (and yes, it was BSTR, not BSTR*). But I
> still have a problem with the safearray.

> STDMETHODIMP CIRServer::NewJob(BSTR name, VARIANT* pVariant)
> {
>  IImpJob* pJob = CreateJob(name);

>  VariantInit (pVariant);
>  pVariant->vt = VT_ARRAY|VT_VARIANT;

>  SAFEARRAY* psa = NULL;
>  SAFEARRAYBOUND bound  = {1, 0};

>  psa = SafeArrayCreate (VT_VARIANT, 1, &bound);
>  if (psa == NULL)
>      return E_OUTOFMEMORY;

>  long i=0;
>  HRESULT hr = SafeArrayPutElement (psa, &i, &pJob);
>  pVariant->parray = psa;

>  return 0L;
> }

>     SafeArrayPutElement returns 80020008 (Bad Variable Type). Doesn't it
> accept my IImpJob*?

>    Thanks before hand.
>    Best wishes. Javier.

> ------------------



> > I assume JobName is BSTR after all, not BSTR*, otherwise the code won't
> even
> > compile.

> > Your problem is you lie about your variant type. You put the type of
> > VT_VARIANT | VT_BYREF, then store a SAFEARRRAY in it, which should have
> been
> > VT_VARIANT | VT_ARRAY.



Wed, 10 Sep 2003 01:57:54 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. HEAP[my.exe]: Invalid Address specified to RtlValidateHeap( 1940000, 1b73290 )

2. Invalid Address specified to RtlValidateHeap

3. Invalid Address specified to RtlValidateHeap

4. Invalid Address specified to RtlValidateHeap

5. Invalid Address specified to RtlValidateHeap

6. Invalid Address specified to RtlValidateHeap (non-dll)

7. "Invalid Address specified to RtlFreeHeap(..)"

8. Invalid Address specified to RtlFreeHeap (Debug in Win2000 Proffesional+SP3)

9. Invalid Address specified to RtlFreeHeap

10. Invalid Address specified to RtlFreeHeap ...

11. Invalid Address specified to RtlFreeHeap( 80000, 859ce0 )

12. Incomplete import address table causes jump to invalid address

 

 
Powered by phpBB® Forum Software