LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

CVI 8.5 Memory

Hello,

 

I am having problems with the following code. This is a simplified version of what I am actually running, but it  shows the problem. I open task manager and use the performance tab to view memory usage. When I run this, the memory used is way above what I would expect. I would expect for every 100 times though the loop memory use should increase 1 meg or so. After running through the program, it should show use of around 2 meg. I start out with around 835 meg in task manager and end up using 2.57 GB. Maybe it is my misunderstanding of realloc, but I tried it using malloc and using a seperate pointer and freeing with the same results. I am using 8.5.0 (279).

 

Any ideas?

 

TZ

 

 

 

#include <ansi_c.h>


#define NULL_CONST       0


int  *main_ptrs;

// Main program. This is where the program starts
int main (int argc, char *argv[])
{
 int  cnt = 0,
   mem_size;
 
 double  integral,
   remainder;

 for (cnt = 0; cnt < 2000; cnt++)
 {
 
  //mem_size = ((cnt + 1) * sizeof(struct void_frame_info));
  mem_size = (cnt * 1000);
 
  realloc(main_ptrs, mem_size);
 
  remainder = modf((double) ((double) cnt / 10.0), &integral);
 
  // Allows the setting of a breakpoint every time the divide by number
  // in the line above results in 0 remainder
  if (remainder == 0.0)
   cnt = cnt;
 }
 // Allows a spot for a breakpoint  
 mem_size = mem_size;
 
 free(main_ptrs);
}
 

Download All
0 Kudos
Message 1 of 10
(4,395 Views)

Hello TZ,

 

Calling realloc is pretty much the same thing as calling malloc, except that the contents of the memory block that you pass in are copied onto the new block. This means that there should be a call to free for each call to realloc, as is the case for malloc. In this case, you're calling realloc 2000 times, but you're only freeing the last block, at the end of your loop. This is a giant memory leak. Instead, you should be catching the return value of realloc (as you would with malloc), then use it, and then free it when you're done with it.

 

Another problem with this code snippet is that you're passing an uninitialized variable to realloc. Because it's a global, its value happens to be NULL, which is okay (essentially, that call becomes completely equivalent to calling malloc) but you shouldn't rely on its value always being NULL. It's compiler-dependent. If it had been some other value, you would have had some nasty runtime error.

 

Luis
0 Kudos
Message 2 of 10
(4,385 Views)

I meant to point out that if your goal is to simply grow the same memory block incrementally, with each iteration of your loop, instead of using the malloc/realloc functions you can use the memory block handle functions in the Programmer's Toolbox. In particular, the NewHandle, SetHandleSize and DisposeHandle functions.

 

Luis

0 Kudos
Message 3 of 10
(4,383 Views)

Thanks for your VERY quick response. I did not try the realloc stuff yet. I am more interested in using the CVI memory functions. Once a handle is created, what next? How do I access the data? I could not find any meaningful help on NewHandle and so on.

 

Thanks,


TZ

0 Kudos
Message 4 of 10
(4,376 Views)

Luis,

 

Thanks again for your help. I am confused on something, the pointer that I pass into realloc alway comes back freed. I tried to free it imediatly and got the error that it was already freed. Is this your experience as well?


TZ

0 Kudos
Message 5 of 10
(4,371 Views)

Hello TZ,

 

If I read the help correctly, realloc moves its previous block when it needs a larger block for continuous free space.

main_ptrs = realloc(main_ptrs, mem_size);

 

As a kind of yellow paper, I always add the pointer type.

Sometimes I calculate the memsize as you did with struct_void_frame_info. If this calculation and the realloc are not on subsequent lines - again as yellow paper -  put the sizeof inside the function call:

main_ptrs = (int *)realloc(main_ptrs, numberelements * sizeof(int));

 

Succes, Jos

0 Kudos
Message 6 of 10
(4,332 Views)

Calling realloc is pretty much the same thing as calling malloc, except that the contents of the memory block that you pass in are copied onto the new block. This means that there should be a call to free for each call to realloc, as is the case for malloc.


 

 

As a side note, is toolbox.c/AppendString() then doing it wrong? I don't see the realloc'ed 'string' being freed.

-----------------------
/* Nothing past this point should fail if the code is working as intended */
0 Kudos
Message 7 of 10
(4,304 Views)

LuisG said:

"Calling realloc is pretty much the same thing as calling malloc, except that the contents of the memory block that you pass in are copied onto the new block. This means that there should be a call to free for each call to realloc, as is the case for malloc. "

 

i'm sorry LuisG but i am not so sure about that one... on the contrary, all papers i read about the C standard library tells me that realloc() takes care of freeing the old memory block itself if necessary. in fact you have to call free() for each block of memory for which you called either malloc() or realloc() with an initial value of NULL. between the initial malloc() and the corresponding free() you may have any number of realloc() you like.

 

however, you are right that the original poster misused realloc by not using the value returned by realloc(). this way, he reallocates a block of memory but still references the original block, which may have been freed and moved by realloc(). that's the reason for the erratic behavior he observes in his program.

the line should read:

main_ptrs = realloc( main_ptrs, mem_size );

then everything will be fine...

 

 

0 Kudos
Message 8 of 10
(4,278 Views)

All,

 

I appreciate the support that you have given me. It is comforting to know there are people out there that care and like to help.

 

I have decided to use the Link List utilities in the toolbox. It appears that it will simplify my code and I have tried it in a small chunk of code and it works exactly as I expect. It does appear a bit slow, but I am in debug mode.

 

Thanks again,


TZ

0 Kudos
Message 9 of 10
(4,276 Views)

Oops. Looks like I goofed. dummy_decoy is right, of course; realloc does free the pointer that you pass in, and the way to use it to pass the same variable that you had previously allocated.

 

TZ: to answer your question about NewHandle, the way you access the memory is by dereferencing the pointer twice. A handle is a pointer to the pointer that actually points to your memory, which is what allows the memory block to be resized without having to change the value of the handle. This is the relevant passage from the NewHandle function help:

 

"The handle is a pointer to a second pointer. It is this second pointer which points to the allocated memory block. This method allows the memory block to be resized (by calling SetHandleSize) without changing the value of the handle."

 

Here's an example, comparing with malloc:

 

int *myIntArray;

 

myIntArray = (int *)malloc (100);

myIntArray[0] =  100;

myIntArray[1] = 100;

...

free ((void *)myIntArray);

 

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

 

Handle myIntArray;

 

myIntArray = NewHandle (100);

((int*)(*myIntArray))[0] = 100;

((int*)(*myIntArray))[1] = 100;

...

DisposeHandle (myIntArray);

 

 

 

 

Message Edited by LuisG on 10-20-2008 11:01 AM
0 Kudos
Message 10 of 10
(4,266 Views)