RE: realloc and Segmentation Fault

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jonathan Shan wrote:

> I am trying to pass the memory address of 'valid' pointer around in
> some functions. Whenever the memory allocated to valid changes, then
> the memory address of 'valid' pointer changes.

Then the problem is that there are two different 'valid's in your program.

Your main function has a pointer 'valid' and allocates some memory for it.
So far so good.

You pass the pointer to func1 or func2: these both have an argument called
'valid'. Now here's where the problem is: this is *not* the same 'valid'
variable as you have in main, it's a copy of it that is local to the
function. So when you write

    valid = insert_to_bucket(valid);

both of these accesses to 'valid' are to the local copy of the original
pointer; in particular, the return value from insert_to_bucket is being
saved in the local copy only and this code does *not* update the value of
'valid' stored in main.

So when you leave func2, the pointer to the newly allocated memory (stored
in the local 'valid') is thrown away and all you have now is the 'valid'
pointer in main which still points to the original allocated memory. But
realloc freed the original allocated memory when it allocated you a larger
block to use instead. So the 'valid' pointer in main doesn't point to any
allocated memory and so when you attempt to use it your program crashes.

So how do you get the new value of 'valid' out of func2 when it has been
changed? There's a few ways you could use: Andrew suggested that you always
return it, i.e.

    struct bucket* func1(struct bucket *valid)
    {
        return func2(valid);
    }
    struct bucket* func2(struct bucket *valid)
    {
        return insert_to_bucket(valid);
    }

and then instead of

        func1(valid);

in main, use

        valid = func1(valid);

(i.e. the same approach you're using with the pointer in insert_to_bucket).

Alternatively, you could pass a pointer to valid into func1 and deference it
there

    void func1(struct bucket **pvalid)
    {
        *pvalid = insert_to_bucket(*pvalid);
    }

and then in main

        func1(&valid);

or, if this is actually C++, you could use a reference to the pointer:

    void func1(struct bucket *&valid)
    {
        valid = insert_to_bucket(valid);
    }

which is more or less the same, except the compiler deals with the
pointer-to-valid stuff automatically for you.

Hopefully that's the problem!
Rup.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux