Thread: Alternative to malloc

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    23

    Alternative to malloc

    Hi,
    I'm working on a project with MPI and have just found out that malloc should not be used as it is not thread-safe. This makes sense as initially I made all my matrices in the form matrix[x][x] but when I changed it to a pointer instead and dynamically created memory for it using malloc my program kept crashing... (system bus error) Seeing as this is the only thing I changed I figured it must be the malloc causing the problem. So my question is what alternative do I have to malloc if I want to dynamically create an array (won't know the size until run-time.. dependent on what is entered on the command line)
    Thanks.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    malloc should be thread-safe if you are using MT version of the CRT...

    If you are not - you have problems that are not connected to the malloc directly but are indicated by the usage of malloc
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    malloc should be thread safe, if you link with a MT standard C library.

    My guess is there are other bugs in your code, and this is just a side-effect.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by stellastarr View Post
    Hi,
    I'm working on a project with MPI and have just found out that malloc should not be used as it is not thread-safe. This makes sense as initially I made all my matrices in the form matrix[x][x] but when I changed it to a pointer instead and dynamically created memory for it using malloc my program kept crashing... (system bus error) Seeing as this is the only thing I changed I figured it must be the malloc causing the problem. So my question is what alternative do I have to malloc if I want to dynamically create an array (won't know the size until run-time.. dependent on what is entered on the command line)
    Thanks.
    Even if your malloc() is not thread safe (which it probably is -- why do you think it is not?), you can wrap it up in a simple lock/unlock to make it thread safe. This isn't as optimal as using a truly thread safe malloc(), but it can be done:

    Code:
    void *malloc_multithread(size_t size)
    {
        void *mem;
    
        lock_the_malloc_lock();
        mem = malloc(size);
        unlock_the_malloc_lock();
        return mem;
    }
    Where lock_ and unlock_the_malloc_lock() lock some global lock. Again, this probably isn't optimal. MT malloc() implementations can play clever tricks to avoid locking in many circumstances (such as allocating from multiple, distinct pools)

    EDIT: Also, it would be pretty silly for a multiprogramming system to not have a thread-safe allocator. Not being able to allocate memory would be a very dumb limitation.

  5. #5
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    alright I think I figured out my problem...
    for the function MPI_Scatter() there is an argument: void* sendbuf.
    When I did double array[6][6] and passed array into this argument everything worked perfectly.
    But if I changed it to double **array and then made a 2D array from this then tried to pass array as the argument the program crashes.
    By passing &array[0][0] the program doesn't crash anymore but I do not get the correct results. So what is the proper way to send **array to this argument?
    Thanks.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by stellastarr View Post
    But if I changed it to double **array and then made a 2D array from this then tried to pass array as the argument the program crashes.
    I assume you are allocating this double **array by malloc'ing an array of pointers, then malloc'ing an array for each pointer? That's not going to work. You have to allocate a contiguous chunk of data.

    Code:
    double *array = malloc(6 * 6 * sizeof(*array));
    In order to index this array you'll have to compute the indexes yourself:

    Code:
    int index = 6 * row + col;

  7. #7
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    alright.. and just to make sure, I would pass array as &array[0] into the argument now?
    Thanks

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by stellastarr View Post
    alright.. and just to make sure, I would pass array as &array[0] into the argument now?
    Thanks
    That's right. "&array[0]" is equivalent to just "array", by the way. I sometimes use the former, sometimes the latter, depending on the context.

  9. #9
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    ok... one last question (hopefully)... How would I send the type double *pivot to the argument of type void* buffer (inside MPI_Bcast)?
    weirdest thing happens:
    Code:
    pivot = malloc(sizeof(double) * n);
    
    for(i=0;i<n;i++)
      pivot[i] = array[i]; // I want to copy the first row of array into pivot (array is actually a 2d array remember, so to get i,j location: i*n + j
    
    // I then print pivot here to make sure the right values are being stored (which they are)
    
    MPI_Bcast(&pivot[0],...); // I also tried just pivot to no avail. Weirdest thing happens.. random numbers of the matrix array seem to end up pivot (from other rows.. and usually sequentially) when other processors receive pivot
    Any suggestions on what the problem could be?
    Thanks.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by stellastarr View Post
    ok... one last question (hopefully)... How would I send the type double *pivot to the argument of type void* buffer (inside MPI_Bcast)?
    weirdest thing happens:
    There's no enough info for me to really guess what's going on here. Can you show the entire call to MPI_Bcast?

    Could it be a synchronization problem? Some other process changing the array between the for-loop and the call to MPI_Bcast?

  11. #11
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    alright here is the full code:
    Code:
    for(k=0;k<5;k++){
    		
    		if (rank == root)
    		{	
    			mult = a_array[k*n + k];
    			for (i=k;i<6;i++)
    				a_array[k*n + i] = a_array[k*n + i]/mult;
    						
    			pivot[0] = a_array[0];
    			pivot[1] = a_array[1];
    			pivot[2] = a_array[2];
    			pivot[3] = a_array[3];
    			pivot[4] = a_array[4];
    			pivot[5] = a_array[5];
    			
    			for(i=0;i<6;i++)
    				printf("%f\t",pivot[i]);
    			printf("\n");
    			
    		}
    		MPI_Barrier(MPI_COMM_WORLD);
    		   MPI_Scatter(&a_array[0],12,MPI_DOUBLE,&temp[0],12,MPI_DOUBLE,root,MPI_COMM_WORLD);
    		MPI_Bcast(&pivot[0],6,MPI_DOUBLE,0,MPI_COMM_WORLD);
    
     		for (i=0;i<2;i++){
     			if ((rank*2 + i) > k){
     				mult = temp[i*2 + k];
     				for (j=0;j<6;j++)
     					temp[i*2 + j] = temp[i*2 + j] - mult*pivot[j];
     				}
    		}
    		mpi_err = MPI_Barrier(MPI_COMM_WORLD);
    		MPI_Gather(&temp[0],12,MPI_DOUBLE,&a_array[0],12,MPI_DOUBLE,root,MPI_COMM_WORLD);
    	}
    	MPI_Barrier(MPI_COMM_WORLD);

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Of course, without a whole bunch of declarations, it doesn't make a lot more sense.

    All those literal constants like 6 and 12 don't make for good reading.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Feb 2006
    Posts
    23
    oh sorry about that... I'm currently in a debug mode so I'm just playing around with small numbers.. was going to change them to a variable when I finally got it working..
    here are all the declarations:
    Code:
            int n = 6;
    	a_array = malloc(sizeof(double *) * n * n);
    	temp = malloc(sizeof(double *) * 2 * n);
    	pivot = malloc(sizeof(double) * n);
    So a_array is an n x n array, temp 2 x n (the work is being divided by 3 processors) and pivot is 1 x n.
    And the 12 is how many elements are sent to each processor... since temp is 2 x 6 = 12.
    Same goes for the Bcast as pivot has 6 elements.
    Hope this clears everything up.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > pivot[0] = a_array[0];
    From this, I conclude they have the same type.

    > a_array = malloc(sizeof(double *) * n * n);
    > pivot = malloc(sizeof(double) * n);
    But this suggests otherwise.

    I'd say the problem is that you're really not allocating enough memory for some of your arrays, so you just end up randomly trashing memory.

    STOP using types in malloc calls would be my suggestion, and read the FAQ.

    p = malloc ( n * sizeof *p );
    is idiot proof, assuming you can get the right value for n in there. It depends on nothing else except getting the declaration of p correct.
    It works for all types, always tastes the same, no mess, no fuss, does exactly what it says on the tin.

    By comparison,
    double *p = malloc ( n * sizeof(double*) );
    is complete garbage, because you're not allocating the correct amount of space, and there is no way for the compiler to tell you otherwise. The first you find out about it is usually some random crash.

    Oh, and when I say declarations, I mean things like
    double *a_array;
    double **temp;
    or what have you.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. malloc + segmentation fault
    By ch4 in forum C Programming
    Replies: 5
    Last Post: 04-07-2009, 03:46 PM
  2. Is there a limit on the number of malloc calls ?
    By krissy in forum Windows Programming
    Replies: 3
    Last Post: 03-19-2006, 12:26 PM
  3. Malloc and calloc problem!!
    By xxhimanshu in forum C Programming
    Replies: 19
    Last Post: 08-10-2005, 05:37 AM
  4. malloc and realloc
    By odysseus.lost in forum C Programming
    Replies: 3
    Last Post: 05-27-2005, 08:44 AM
  5. malloc() & address allocation
    By santechz in forum C Programming
    Replies: 6
    Last Post: 03-21-2005, 09:08 AM