Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Aug 2008 18:22:21 +0200
From:      Jordi Moles Blanco <jordi@cdmon.com>
To:        Giorgos Keramidas <keramida@ceid.upatras.gr>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: error allocating memory with realloc(). how can i increase	max_allowed in the system? [solved]
Message-ID:  <48A1B8BD.3080306@cdmon.com>
In-Reply-To: <87fxpab4gy.fsf@kobe.laptop>
References:  <48A1A613.5020407@cdmon.com> <87fxpab4gy.fsf@kobe.laptop>

next in thread | previous in thread | raw e-mail | index | archive | help
Hello,

thank you very much for your time and help, i had completely 
misunderstood how realloc() works.

i though i was able to write some C code but now i feel a complete 
newbie, hehehe.

anyway... that made everything clear to me and now my script is working 
like a charm.

thanks for everything

En/na Giorgos Keramidas ha escrit:
> On Tue, 12 Aug 2008 17:02:43 +0200, Jordi Moles Blanco <jordi@cdmon.com> wrote:
>   
>> Hi,
>>
>> i'm running a FreeBSD 7.0 amd64 machine and struggling with some C
>> code i'm writing.
>>
>> I've had some trouble with this home-made script as it keeps crashing
>> while launching a "realloc()" call.
>>
>> I narrowed down the problem and here i'm sending you a short example of
>> code that crashes:
>>
>> *************
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> int main()
>> {
>>
>>        int midataula;
>>
>>        midataula = 3000;
>>
>>        char *missatge = (char *)malloc(midataula * sizeof(char));
>>
>>        missatge[0]='h';
>>        missatge[1]='o';
>>        missatge[2]='l';
>>        missatge[3]='a';
>>
>>        printf("\n\ntaula1: %s",missatge);
>>
>>        int voltes;
>>        voltes = 0;
>>
>>        while(voltes<4)
>>        {
>>                midataula = midataula+500;
>>                realloc(missatge, midataula * sizeof(char));
>>                voltes++;
>>        }
>>     
>
> There's your problem.  realloc() works fine, but it *returns* the new
> pointer; it does _not_ modify missatge "in place".
>
> The program should work fine if you use size_t for midataula (it is the
> 'size' of an array, which may not necessarily fit in an 'int'), and if
> you use realloc() correctly, as in:
>
>         #include <stdlib.h>
>         #include <err.h>
>
>         size_t midataula;
>         char *missatge;
>
>         /*
>          * DON'T cast the result of malloc().  It may 'hide' the bug of
>          * a missing <stdlib.h> include, and cause troubles when
>          * malloc() is implicitly defined by the compiler as:
>          *
>          *        int malloc(...);
>          *
>          * On a 64-bit machine converting a 64-bit pointer to `int' will
>          * lose the high-order 32 bits of the address, and you will try
>          * to access unexpected memory areas.
>          */
>         midataula = 3000;
>         missatge = malloc(midataula * sizeof(*missatge));
>         if (missatge == NULL)
>                 err(1, "malloc");
>
> Then when you use realloc() keep both midataula and missatge in
> temporary copies until you are sure that realloc() worked:
>
>         while (voltes < 4) {
>                 char *tmp;
>                 size_t newsize;
>
>                 newsize = midataula + 500;
>                 tmp = realloc(missatge, newsize * sizeof(*missatge));
>                 if (tmp == NULL)
>                         err(1, "realloc");
>
>                 /*
>                  * Now that you know the resize has succeeded, update
>                  * midataula and missatge.  realloc() is allowed to
>                  * relocate missatge.  See the following note in its
>                  * manpage:
>                  *
>                  *   Note that realloc() and reallocf() may move the
>                  *   memory allocation, resulting in a different return
>                  *   value than ptr.
>                  */
>                 midataula = newsize;
>                 missatge = tmp;
>         }
>
> Right now you are calling realloc() as:
>
>                 realloc(missatge, newsize * sizeof(*missatge));
>
> and throwing away the resulting pointer.  The first time that realloc()
> discovers that the `resized' vector cannot fit in its original location,
> it relocates the array, and returns the new location.  You throw away
> that location and your next iteration through the loop tries to access
> an invalid (already freed) memory region.
>
> That's what causes your segmentation fault.
>
> _______________________________________________
> freebsd-questions@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-questions
> To unsubscribe, send any mail to "freebsd-questions-unsubscribe@freebsd.org"
>   




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?48A1B8BD.3080306>