Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #26321

Re: Failing Malloc

From James Kuyper <jameskuyper@verizon.net>
Newsgroups comp.lang.c
Subject Re: Failing Malloc
Date 2012-09-13 17:57 -0400
Organization A noiseless patient Spider
Message-ID <505256DA.80605@verizon.net> (permalink)
References <k2qq2i$aba$1@speranza.aioe.org> <L864s.41309$Ax.33657@fx18.am4> <k2qrlc$ea5$1@speranza.aioe.org> <e95d81dd-908d-42cb-bdd2-893456fe16f3@e29g2000vbm.googlegroups.com> <k2tf88$ki9$1@speranza.aioe.org>

Show all headers | View raw


On 09/13/2012 04:21 PM, Eric wrote:
> On Wed, 12 Sep 2012 13:46:51 -0700, Paul N wrote:
...
>> If your program has an alternative way of working which uses less memory
>> (say, for example, a slower method) you could put in a new malloc asking
>> for less memory and see if that works. Or you could allocate more memory
>> than you need early in the program, so you've got a bit already to hand
>> when you run a crucial bit of the program. Or you could tell the user
>> that unfortunately the program can't do what was requested.
>>
>> Getting more memory from the stack seems a little risky, as there are
>> normally less checks whether it worked. Swapping your own program's data
>> out to disk might be a possibility if you keep track of what you have
>> done. Swapping other programs out to disk is system-specific, if you
>> want to try this then other newsgroups will be able to give better help.
> 
> What I mean is, imagine a very large allocation say 4MB. Maybe that's not 
> available in one chunk, however 4 seperate 1MB allocations could succeed. 
> That sort of thing.


Here's code that shows how to do something like that:
#define BLOCK_SIZE 0x40000000
#define NUM_BLOCKS 4
#define BUFFER_SIZE (NUM_BLOCKS * BLOCK_SIZE)

// Note: on many systems the calculation of BUFFERSIZE will overflow

int func(void)
{
    void *blocks[NUM_BLOCKS] = {0};
    int numb;
    blocks[0] = malloc(BUFFER_SIZE);
    // Even if the calculation doesn't overflow, the conversion to
    // size_t may cause unsigned wrap-around. I'll leave it as an
    // exercise for the reader to figure out how to deal with those
    // possibilities.

    if(blocks[0])
    {
        for(numb=0; numb<NUM_BLOCKS-1; numb++)
            blocks[numb+1] = blocks[numb] + BLOCK_SIZE;
    }
    else
    {
        for(numb=0; numb<NUM_BLOCKS && blocks[numb]=malloc(BLOCK_SIZE);
	   numb++);
    }
    if(numb == NUM_BLOCKS)
    {
        // code that works with blocks[];
        // the key thing is that this code doesn't care whether or not
        // the block of memory pointed at by block[1] immediately
        // follows the block pointed at by block[2].
    }
    else
    {
        // error handling for insufficient memory
    }
    while(numb>0)
        free(blocks[--numb]);
}

However, if you can write your code to work with 4 smaller blocks, it's
probably best to always allocate 4 blocks, rather than one large one.

> By stack I mean essentially a local array, i.e.
> func()
> {
>   char buf[1000]; /* <--- example */
>   /* buf can never be Null */
> }
> 
> Note, that in this case, Null can never be returned for the array.

OK, that's a different approach. Here's some code that shows how
something like that could be done:

int called(void*); // This function does the actual work.

int caller(void)
{
    void *p = malloc(BUFFER_SIZE);
    if(p)
         return called(p);
    else
    {
         char buf[BUFFER_SIZE];
         return called(buf);
    }
}

Note: if p is non-null, it's guaranteed to be correctly aligned for any
object type. No such guarantee applies to buf. If called() makes use of
the pointer in any way that requires a special alignment, you need to do
something to make sure that 'buf' is suitably aligned. In C99, you
should declare the parameter of called() as being a pointer to an object
with suitable alignment requirements, and declare buf to be an array of
that same object type. C 2011 adds some new alignment-oriented features
that allow for more exotic ways of achieving that same purpose, but this
is still the most appropriate method to use.

On many systems, the memory pointed at by 'p' comes out of the heap,
while 'buf' resides on the stack, but the C  standard doesn't use those
terms, and does not require that such things even exist. The stack and
the heap could be two separate memory pools, or they could be different
ends of the same block of memory; more complicated alternatives exist as
well. If they are from a single block of memory, not having enough heap
for malloc() to succeed could correspond to not having enough stack for
the allocation of buf to occur. If that's the case, the behavior of that
program is undefined, and there's nothing you can do to prevent that,
anticipate that, or deal with it.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Failing Malloc Eric <nospam@nospam.com> - 2012-09-12 20:07 +0000
  Re: Failing Malloc Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2012-09-12 22:12 +0200
    Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-12 14:25 -0700
  Re: Failing Malloc Andrew Cooper <andrew@nospam.example.com> - 2012-09-12 21:21 +0100
    Re: Failing Malloc Eric <nospam@nospam.com> - 2012-09-12 20:34 +0000
      Re: Failing Malloc Paul N <gw7rib@aol.com> - 2012-09-12 13:46 -0700
        Re: Failing Malloc Eric <nospam@nospam.com> - 2012-09-13 20:21 +0000
          Re: Failing Malloc Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-09-13 17:31 -0400
          Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 17:57 -0400
      Re: Failing Malloc John Gordon <gordon@panix.com> - 2012-09-12 20:55 +0000
        Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-12 14:33 -0700
        Re: Failing Malloc falk@rahul.net (Edward A. Falk) - 2012-09-13 22:43 +0000
      Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 17:37 -0400
      Re: Failing Malloc Johann Klammer <klammerj@NOSPAM.a1.net> - 2012-09-13 08:57 +0200
  Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 17:20 -0400
    Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-13 09:27 +1200
      Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 17:56 -0400
        Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-13 10:28 +1200
          Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-12 18:57 -0400
            Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-12 16:21 -0700
            Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-13 12:07 +1200
              Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 13:18 -0400
                Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-14 07:37 +1200
                Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 16:05 -0400
                Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-13 14:21 -0700
                Re: Failing Malloc James Kuyper <jameskuyper@verizon.net> - 2012-09-13 17:38 -0400
                Re: Failing Malloc William Ahern <william@wilbur.25thandClement.com> - 2012-09-13 14:03 -0700
                Re: Failing Malloc Ian Collins <ian-news@hotmail.com> - 2012-09-15 10:01 +1200
            Re: Failing Malloc Philip Lantz <prl@canterey.us> - 2012-09-14 02:50 -0700
  Re: Failing Malloc Kaz Kylheku <kaz@kylheku.com> - 2012-09-12 21:36 +0000
  Re: Failing Malloc Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-09-12 17:41 -0400
  Re: Failing Malloc Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-09-12 16:07 -0600
    Re: Failing Malloc "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-09-12 16:03 -0700
  Re: Failing Malloc Kenneth Brody <kenbrody@spamcop.net> - 2012-09-12 19:24 -0400
  Re: Failing Malloc The Great Firewall of China Blue <chine.bleu@yahoo.com> - 2012-09-12 16:34 -0700
  Re: Failing Malloc Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-09-13 00:14 -0700

csiph-web