[BUG][malloc] In-consistent behavior in malloc.

Hi ,

        I have observed an in-consistent behavior in malloc/free . 

Case 1 :
struct TMemFile
{
char* pFIle;
}

main1()
{
TMemFile mptr[20000] ; // Stack Variable
for ( 20000 times)
{
mptr*.pFile = malloc 100 KB.
}

        for (20000 times) 
        { 
                    Free(mptr.pFile); 
        } 

}

Case 2:
struct TMemFile
{
char* pFIle;
}

main2()
{
TMemFile* mptr[20000] ; // Heap Variable
for (20000 times)
{
mptr* = malloc (TMemFile);
mptr*->pFile = malloc 100 KB;
}
for (20000 times)
{
free(mptr*->pFIle);
free(mptr*);
mptr* = NULL;
}

}

In Case 1, after executing main1() memory is getting released and
VirtualMemory is coming down (reading from top).

In Case 2, after executing main2() memory is getting released and
VirtualMemory is not coming down***** (reading from top).

  1. Why exceptional behavior for pointer variable (case 2
    TMemFile* ) ?

  2. If we consider case 2 then what are the different consequence for
    below two scenerio,

         i) Normal executable. 
    
         ii) Dynamically loaded libs (open by dlopen())*

Please tell us next time the language you use and try to give a compilable example of the program which causes the error. Seem to be a macroed C though. And use Code-Tags, please

Your comment is wrong and will lead into the confusion which is visible in your following code. What you did here is not allocating a variable on the heap, but allocating a pointer to an array (which is again a pointer to its first element) on the stack:
TMemFile*: The type -> Pointer to TMemFile
mptr[20000]: array of this type named mptr -> Pointer to an array of 20000 TMemFiles.

When you want to have an Array of mptr on the heap, use

TMemFile *mptr;

So you will get a pointer to TMemFile on the stack and can allocate memory on the heap for its elements. If you want to allocate 20000 elements of TMemFile on the heap now, just

mptr = malloc(20000 * (sizeof(TMemFile)));

and address the elements through offsets.

PS: Your cleanup is wrong. Free the elements in the for-loop, then (outside the loop) free the array itself.

Here pls find full code,

typedef char TChar;
typedef long long TInt8;

struct TMemFile
{
TChar* pFile;
};

int main1()
{
unsigned TESTSIZE = 20000;
TInt8 MEMVFS_CLUSTER_SIZE = 1024 * 100;
TMemFile* mptr[TESTSIZE];
TChar n[256];

printf(“Enter 1 to start stress malloc”);
scanf("%s",n);

for (unsigned i = 0; i < TESTSIZE ; ++i)
{
mptr* = (TMemFile)malloc(sizeof(TMemFile));
TMemFile* memFile = mptr*;

memFile-pFile = (TChar*)malloc(MEMVFS_CLUSTER_SIZE);
memset((TChar*)memFile->pFile,0,MEMVFS_CLUSTER_SIZE);
strcpy((TChar*)memFile->pFile,“abcd”);
}

printf(“Enter 1 to start stress de-alloc”);
scanf("%s",n);

for (unsigned i = 0; i < TESTSIZE ; ++i)
{
void ptr = (void)mptr*->pFile;
free(ptr);
free(mptr*);
mptr*= NULL;
}

printf(“Enter 1 to quit”);
scanf("%s",n);

return 0;
}

int main()
{
main();
}*****

Your assumption that VM usage will go down when free() is called isn’t valid. In Unix/Linux processes can only increase the heap, not shrink it. If a heap page isn’t needed it is mapped out of the working set, that’s all.

Why in the first case of my first post VM is comming down after free ?

Perhaps top was measuring the pages in use (and those measurements need to be taken with a grain of salt, because it may not be measuring what you believe it is) and there are no references active to those pages, whereas in the second page, it’s still in the malloc allocation pool (maintained by the malloc library, not the kernel).

In any case you have little control over how VM is allocated in a Linux process. There is a brk() syscall to extend the data segment, but there is not a corresponding syscall to contract it. That’s the way it is.