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 <[EMAIL PROTECTED]> 
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 "[EMAIL PROTECTED]"

_______________________________________________
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to