LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

malloc() in debug mode allocates wrong amount

I knew I had a small memory leak in my software, so I downloaded memwatch (http://www.linkdata.se/sourcecode.html).  Running the sample (test.c) in debug mode, a request to malloc for 250 bytes in a specific context only returns 224 bytes (it may be because of the cast to a structure type, and the compiler rounding the size).  code is as follows (very chopped):

struct mwData_ {
    mwData*     prev;   /* previous allocation in chain */
    mwData*     next;   /* next allocation in chain */
    const char* file;   /* file name where allocated */
    long        count;  /* action count */
    long        check;  /* integrity check value */
    size_t      size;   /* size of allocation */
    int         line;   /* line number where allocated */
    unsigned    flag;   /* flag word */
    };

mwMalloc(size) {
    mwOverflowZoneSize = 4;
    mwDataSize = sizeof(mwData_); //32 bytes
    needed = mwDataSize + mwOverflowZoneSize*2 + size; //requested size + 40
    mw = (mwData*) malloc( needed );
    ptr = ((char*)mw) + mwDataSize;
    ptr += mwOverflowZoneSize;
    memset( ptr, MW_VAL_NEW, size );


calling mwMalloc(210), needed=250, will error out at the memset:
FATAL RUN-TIME ERROR:   "memwatch.c", line 935, col 13, thread id 0x00000950:   Array argument too small (188 bytes).  Argument must contain at least 210 bytes (210 elements)

for some reason, compiling in debug mode, only 224 bytes total are being allocated, whereas in release mode, it will allocate the full 250 bytes that are requested.  Is this a bug in the compiler?  I have a workaround for this problem, so it works in debug mode, but seems silly that malloc doesn't return what you ask it for.

Workaround:
replace
    mw = (mwData*) malloc( needed );
with
    ptr = (char*)malloc( needed );
    mw = (mwData*)ptr;


thanks for the help,
~Chip
0 Kudos
Message 1 of 7
(4,329 Views)

Hello Chip,

In order to further isolate when this happens, I have a few folllow-up questions for you.  Which version of CVI are you using, and do you see the same behavior when you change your debugging level to "No Runtime Checking" (Options >> Build Options >> Debugging Level)?

Thanks.

Wendy L
LabWindows/CVI Developer Newsletter
0 Kudos
Message 2 of 7
(4,314 Views)
Can't believe I forgot the version that I'm running: 7.1.1

After disabling Run Time Checking, the error went away.

~Chip
0 Kudos
Message 3 of 7
(4,298 Views)

When debugging, CVI stores type information about the pointer and uses it for runtime checking. If you use the struct pointer for example, CVI expects that pointer to point to memory where the size of allocated memory is an integer multiple of the size of the struct(since in most cases, you will be using that pointer to point to arrays of structs or a single struct). In your case, you actaully allocate the memory neede by the struct plus a little more and looks like this might be throwing off the user protection to give you the error. 

malloc is doing its job ok, its just the user protection code did not expect a pointer of a particular type to have that size.

To avoid this error, use SetBreakOnProtectionErrors to turn off the error notifications around this code. I'll file a report to see if we can improve this in the future.
Bilal Durrani
NI
0 Kudos
Message 4 of 7
(4,290 Views)
Thanks for the response and information, Bilal.  I tried using SetBreakOnProtectionErrors to allow execution of the runtime checking during other parts of the test application, but found numerous places the function would need to be called, which isn't worth the hassle compared to using the quick-fix I came up with earlier.

Thank you for looking into it so quickly.

edit:  I now wonder about the response: "
the user protection code did not expect a pointer of a particular type to have that size".  The memset that's bombing is against a char*, not the structure def itself.  Does CVI keep tabs on what the original definition of an allocated memory space is set aside for, and check against that during runtime checking; instead of just making sure the memory being accessed is within the allocated block?

~Chip

Message Edited by cbaxter on 08-18-2005 12:32 PM

0 Kudos
Message 5 of 7
(4,289 Views)


That's what it's looking like right now. CVI seems to track the original type information for its runtime checking, not the actual number of blocks of memory allocated. I added this in the report I filed, so that this behavior will be documented better.



Bilal Durrani
NI
0 Kudos
Message 6 of 7
(4,251 Views)
Thanks, Bilal, that's exactly what I wanted to know.  Keep up the great support!

~Chip
0 Kudos
Message 7 of 7
(4,239 Views)