RLPext->malloc problem ? how to free memory?


typedef struct {
	double real;
	double imag;
	
}COMPLEX;


 void FFT2D(COMPLEX* c, int nx, int ny, int dir)
      {
           COMPLEX* Output;
           Output = RLPext->malloc(25600);
		 
	RLPext->free(Output);
           
        }

in this function first time it runs perfectly but second time code is hang . any suggestion?

You are probably running into a memory fragmentation problem due to low memory on your board. An easy fix would be working with a static array instead “CMPLEX Output[1600]”.

This article explains the issue Dynamic Memory Allocation and Fragmentation in C and C++

4.2? What device?

@ Gus - it is 4.1

@ Farsa - i also trying to use static array but problem remain same.

i can resize the array .now my array size is just 100. but problem remain same.


  COMPLEX *Output;
  Output = RLPext->malloc(100);

  RLPext->free(Output);

Biren, you were asked what device, I don’t think you’ve answered that yet. Might give some other valuable info to the folks who know this stuff…

@ Brett - this is my device info.


@ taylorza -
i am using Fez Spider

HalSystemInfo.halVersion:               4.1.2821.0
HalSystemInfo.halVendorInfo:            Microsoft Copyright (C) Microsoft Corporation.  All rig
HalSystemInfo.oemCode:                  255
HalSystemInfo.modelCode:                0
HalSystemInfo.skuCode:                  65535
HalSystemInfo.moduleSerialNumber:       FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
HalSystemInfo.systemSerialNumber:       FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
ClrInfo.clrVersion:                     4.1.2821.0
ClrInfo.clrVendorInfo:                  Microsoft Copyright (C) Microsoft Corporation.  All rig
ClrInfo.targetFrameworkVersion:         4.1.2821.0
SolutionReleaseInfo.solutionVersion:    4.1.8.0
SolutionReleaseInfo.solutionVendorInfo: GHI Electronics, LLC
SoftwareVersion.BuildDate:              Dec 22 2011
SoftwareVersion.CompilerVersion:        410561
FloatingPoint:                          True
SourceLevelDebugging:                   True
ThreadCreateEx:                         True
LCD.Width:                              320
LCD.Height:                             240
LCD.BitsPerPixel:                       16
AppDomains:                             True
ExceptionFilters:                       True
IncrementalDeployment:                  True
SoftReboot:                             True
Profiling:                              False
ProfilingAllocations:                   False
ProfilingCalls:                         False
IsUnknown:                              False

Can you post the complete FFT2D function? That way we can see the malloc in it’s context. I find it very strange that you allocate 25600 bytes instead of 1600 * sizeof(COMPLEX). Also strange why you would not check the returned pointer against NULL before proceeding.

Allocating 100 bytes and casting them to a COMPLEX array will give you an array of 6.25 COMPLEX elements. So if you want 100 COMPLEX elements in your array, you should do

COMPLEX* Output = (COMPLEX*)malloc(100 * sizeof(COMPLEX))

It is possible that the code is going out of bounds because of that, which will mess up the heap desciptors of other allocated blocks and make the whole malloc/free functionality fail.

When calling malloc() a part of the heap will be reserved, and the underlying memory manager will add a struct with heap description (containing the size of allocated block) just before the pointer it returns. So if you allocate 2 buffers, the heap will look like this:

[HEAP_DESCRIPTOR1][ALLOCATED_BLOCK1][HEAP_DESCRIPTOR2][ALLOCATED_BLOCK2]

If the code goes out of bounds on ALLOCATED_BLOCK1, then it overwrites the HEAP_DESCRIPTOR2 and the rest of the heap gets unpredictable and corrupt.

@ WouterH -


typedef struct {
	double real;
	double imag;
	
}COMPLEX;

COMPLEX Fourier[25600]; 

 int ForwardFFT(unsigned int *generalArray, void **args, unsigned int argsCount,
                 unsigned int *argSize)
{
   unsigned char *GreyImage = (unsigned char*)args[0];
   int width = *(int*)args[1];
   int height = *(int*)args[2];
    //unsigned char *Grey = (unsigned char*)args[3];
	
	index=0;
    for (i=0;i<=width -1;i++)
		{
            for (j = 0; j <= height - 1; j++)
             {
				
                  Fourier[index].real = (double)GreyImage[index];
                  Fourier[index].imag = 0;
                  index++;
             }
		}

	  FFT2D(Fourier, width, height, 1);	

   return (0);
}
   

 void FFT2D(COMPLEX *c, int nx, int ny, int dir)
      {
           COMPLEX *Output;
           Output = RLPext->malloc(25600 * sizeof(COMPLEX));
		 
           ////Output = c;
           //// Transform the Rows 
  
          /*  for (j = 0; j < ny; j++)
            {
                for (i = 0; i < nx; i++)
                {
                    real[i] = c[j*ny+i].real;
                    imag[i] = c[j * ny + i].imag;
                }*/
                // Calling 1D FFT Function for Rows
				
           //     m =(int)Log(nx,2);//Finding power of 2 for current number of points e.g. for nx=512 m=9
				
           //     FFT1D(dir, m,real,imag);
				

				
                /*for (i = 0; i < nx; i++)
                {

                    Output[j * ny + i].real = real[i];
                    Output[j * ny + i].imag = imag[i];
                    
                }*/
               
           // }

            // Transform the columns  
            //*real = new double[ny];
            //imag = new double[ny];*/

            //for (i = 0; i < nx; i++)
            //{
            //    for (j = 0; j < ny; j++)
            //    {

            //        real[j] = Output[j * ny + i].real;
            //        imag[j] = Output[j * ny + i].imag;
            //        
            //    }
            //   
            //    // Calling 1D FFT Function for Columns
            //   // m = (int)Log((double)ny, 2);//Finding power of 2 for current number of points e.g. for nx=512 m=9
            //  //  FFT1D(dir, m,real,imag);
            //    for (j = 0; j < ny; j++)
            //    {
            //        Output[j * ny + i].real = real[j];
            //        Output[j * ny + i].imag = imag[j];
            //        
            //    }
            //   
            //}

			//// transfer output values in to fourior///////////////
		/*	index=0;
            for (i=0;i<=Width -1;i++)
			{
                for (j = 0; j <= Height - 1; j++)
                {
                    Fourier[index].real = Output[index].real;
                    Fourier[index].imag = Output[index].imag;
                    index++;
                
			}*/

			RLPext->free(Output);
            // return(true);
			//return Output;
        }

in this code fft2d function not working properly second time.

I see a static array which consumes 400kB of RAM

COMPLEX Fourier[25600]; 

Then the FFT2D tries to allocate another 400kB of RAM, that’s already 800kB of RAM, and RLP only has 1MB available for code and data. So it is very likely that the first malloc call already fails.

I suggest you implement Fast Fourier transformations that work on with a single buffer, like this one: Fast Fourier transform — FFT — Librow — Digital LCD dashboards for cars and boats

Also consider using float instead of double if your application doesn’t require high precision, because the EMX module used on the FEZ Spider doesn’t have an FPU.

@ WouterH - yes but rlpext->free releseing 400kb Ram ? how to relese memory is there any other way?

I agree that the code should not crash the board. If malloc couldn’t allocate the memory block, it should return NULL, and calling free on NULL should do nothing.
So I suggest you further simplify the code so GHI is able to reproduce it on their end.

@ WouterH - In a perfect world or any language run time library other than C you are correct. This has been an issue for as long as malloc and free have existed. free makes the assumption that you as the programmer are smart enough to check that the pointer you are supplying is valid and pointing to malloced memory. Failure to do so will result in undefined behavior.
So I would suggest that when doing RLP, you check the value returned by malloc and ensure that you don’t try to free anything other that a successfully supplied pointer from malloc.

edit:
The latest standard, WG14/N1124 , does say that if the value is NULL no action is taken. so if the compiler matches the version of the standard I just looked at, then your assertion is correct.

What the heck here’s the link: www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf