Re: Access violation with heap memory



Pretty obvious: see below
On Fri, 23 Jun 2006 19:50:09 +0500, "Adeel" <dontWantSpam@All> wrote:

Hi,

I'm getting a runtime access violation using heap memory that was
allocated in another function. The details follow...


I have a setup in which I pass a pointer to a secondary function (in
another dll) which allocates a buffer dynamically, populates it and
returns. Now, when I try to access the buffer in the main function, I
get a runtime access violation message. The code below will help
clarify this...

<CODE>
void fillBuf (char *p)
{
*****
You pass in the local variable p, which is probably uninitialized. You initialize it. You
return. The value of the initialization disappears, and you have a storage leak, because
the caller's pointer did not get updated.

Why are you using 'char'? This limits you to 8-bit character sets, and the use of new in
this context in any case suggests that you should be using CStrings instead of using
something as primitive as writing 1975 on a PDP-11 (there is no distinction here between
the use of new and malloc, so this is just PDP-11 code updated with fancier syntax).
****
p = new char [10];
//fill the buffer
}

void useBuf ()
{
char *x = NULL;

fillBuf(x);
****
The value of x, upon return from fillBuf, is NULL. Because you have done nothing
whatsoever to update the value of x.
****

// access populated buffer
// e.g. char z = x[3]; //<< ACCESS VIOLATION
****
Yep. That's what I'd expect to get accessing memory location 0x00000003, which is what
you just tried to do
****

delete x;
*****
Since x is NULL, this has no meaning
****
}
</CODE>


I understand that this is probably bad design... 'new' and 'delete'
should happen in the same scope but the problem is I don't know the
size of the buffer beforehand, so can't allocate it before the calling
the secondary function.
*****
It is bad design because it uses 'char', because it does 'new' someplace other than where
it would be useful, etc. A better approach would be

void FillBuf(CString & p)
{
...fill string p with text
}

void CallerOfFillBuff()
{
CString x;
FillBuf(x);
... use values in x
}

Note that there is no need to allocate storage until you are in the FillBuf, and the way
in which you allocate it depends on how you are filling the string. This code is
Unicode-aware, which means it will nicely conver to Unicode (the use of 'char' should be
considered to be used only in very special, exotic circumstances, not as part of ordinary
programming style, where LPTSTR, LPCTSTR and TCHAR should be used).

Here are several options for implemented FillBuf:

p = _T("This is a test");

TCHAR buffer[SOMESIZE];
....fill in buffer contents terminated with 0 character
p = buffer; .

TCHAR buffer[SOMESIZE];
....fill in buffer contents with n chracters, not necessarily terminated with 0 character
p = CString(buffer, n);

....anticipating the receipt of n bytes
LPTSTR t = p.GetBuffer(n);
....fill in t[m] for 0 <= m <= n-1
p.ReleaseBuffer(m);

You need to say something about how you fill the data in when you are inside the FillBuf
function.

If it is raw bytes that can contain embedded 0 bytes, then char is not really a good
solution. In that case, I might do

CArray<BYTE, BYTE>x;
FillBuff(x);

void FillBuff(CArray<BYTE, BYTE> & p)
{
p.SetSize(...desired size);
set values in p[0]..[p.GetSize - 1];
}

What makes you think that multithreading is safe if you DON'T use CArray? it is every bit
as dangerous, or harmless, as the case may be. In fact, I use CArray and CString to pass
values across thread boundaries all the time, and it works perfectly.
joe


Now you might say I break the call down to two steps... use the first
to fetch the size, use the size to allocate the buffer, then issue the
second call to get it populated. But is there a way to do this in one
call?

Or alternatively, how would you design a solution to such a scenario?

I can think of passing a reference to a CArray object accross to the
secondary function... but for some reason, I'm not entirely
comfortable with that... because later, there might be threads
involved in my program and I don't want to run into complications...
better stick with primitive types...



Thanks for all your time.

Adeel

Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Access violation with heap memory
    ... I'm getting a runtime access violation using heap memory that was ... I have a setup in which I pass a pointer to a secondary function (in ... Now, when I try to access the buffer in the main function, I ... so can't allocate it before the calling ...
    (microsoft.public.vc.mfc)
  • Re: Access violation with heap memory
    ... I'm getting a runtime access violation using heap memory that was ... Now, when I try to access the buffer in the main function, I ... so can't allocate it before the calling ...
    (microsoft.public.vc.mfc)
  • Re: Access violation with heap memory
    ... I have a setup in which I pass a pointer to a secondary function which allocates a buffer dynamically, ... Now, when I try to access the buffer in the main function, I get a runtime access violation message. ... should happen in the same scope but the problem is I don't know the size of the buffer beforehand, so can't allocate it before the calling the secondary function. ... That gives you two memory managers, one in the exe and another in the DLL, and allocating from one and deleting in the other won't work. ...
    (microsoft.public.vc.mfc)
  • Re: Strings again :(
    ... char szBuf; ... Apparently due to terminal brain damage on the part of the documentation team, ... Considering the choice of WORD to express buffer length, the maximum size of the buffer is 64K TCHAR's, so I would just allocate a buffer of this size, and pass it to the API. ... I think that 64KB is fine to allocate in these days of GigaBytes:) ...
    (microsoft.public.vc.mfc)
  • Re: Porting old streambuf code to current C++ library
    ... // once the buffer overflows. ... // Return the start address of the buffer you allocated for setbuf ... char * mybase; ... // is changed because all destructors allocate a buffer. ...
    (comp.unix.programmer)

Loading