Thread: [C malloc/free] ~ free-ing the allocated memory gives c0000005 Windows error

  1. #1
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14

    Question [C malloc/free] ~ free-ing the allocated memory gives c0000005 Windows error

    Hi everybody!

    I hope you all had a merry christmas... =)

    ....because I need your help!! >.<


    I'm new to C and I'm getting to like this language more and more at every step I take, but I keep banging my head against several walls.

    Today it's the "malloc/free" wall.

    I've built an exercise to learn how to pass values and memory pointers to functions. It's more like a simple "test my knowledge" thing, actually, but still good enough to understand and exercise logic.

    The exercise is very simple:
    - given two "int" variables, pass their values to a function that returns their sum; then print it on the screen
    - given a structure containing three "int" elements, allocate memory and pass its pointer to a function that calculates the product of the first two elements and saves it in the third one; then print it on the screen

    No problems AT ALL with the first part. Happy!!

    The second part, instead, works great until I use "free" to de-allocate memory.

    For a matter of speed, I've written it partly with italian words (my language), but I'll translate the "printf" messages so that you know what's happening.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    
    
    //----------------------------
    //----------------------------
    unsigned long secondary();
    
    int pass_struct ();
    
    struct test
    {
        int numero1;
        int numero2;
        int prodotto;
    };
    //----------------------------
    //----------------------------
    
    
    
    //----------------------------
    //----------------------------
    int main(void)
    {
        //---------------------------- PASSAGGIO DI DUE VALORI SEPARATI COME PARAMETRI PER UNA CHIAMATA AD UNA FUNZIONE
        unsigned long a, b, result;
    
    
        a = 2495383;
        b = 34934059;
    
        result = secondary (a, b);
    
        printf("a = %lu\nb = %lu\n\na+b = %lu\n\n", a, b, result);
    
        //----------------------------
    
    
        //---------------------------- PASSAGGIO DI UN PUNTATORE STRUTTURA COME PARAMETRO PER UNA CHIAMATA AD UNA FUNZIONE
        struct test * oggetto1;
    
        oggetto1 = malloc(sizeof(oggetto1));
    
        printf("Allocated oggetto1 at the address %p\n\n", oggetto1);
    
        oggetto1->numero1 = 2;
        oggetto1->numero2 = 7;
        oggetto1->prodotto = 0;
    
        oggetto1 = pass_struct(oggetto1); //<<-- Actually I shouldnt need to assign the returned value, it would be enough to write "pass_struct(oggetto1)"; right?
    
        printf("Executed call for pass_struct. Address oggetto1: %p\n\n\n", oggetto1);
    
        printf("numero1 = %i\nnumero2 = %i\nnumero1 * numero2 = %i\n\n", oggetto1->numero1, oggetto1->numero2, oggetto1->prodotto);
    
        free(oggetto1); //<<-- Why the heck does it give an error!?!?!??!? >.<
        //----------------------------
    
        return 0;
    }
    //----------------------------
    //----------------------------
    
    
    //----------------------------
    //----------------------------
    unsigned long secondary (unsigned  long uno, unsigned  long due)
    {
        return uno + due;
    }
    //----------------------------
    //----------------------------
    
    
    //----------------------------
    //----------------------------
    int pass_struct (struct test * pointer)
    {
        pointer->prodotto = pointer->numero1 * pointer->numero2;
    
        return pointer; //<<-- Absolutely useless, since the pointer doesnt change and it remains in the main function, aint it so? =o
    }
    //----------------------------
    //----------------------------

    The error comes out randomly, not at every execution; clear sign that it's bound to memory addresses, as if the address I'm trying to free is no longer reserved and gets used by another application.

    I've tried to analyze the whole thing excluding the most common errors like scopes, re-assignements and the likes.
    As you can see I've even set an extra "printf" after the call for the external function to ensure the address inside the "oggetto1" variable is still the same as before.

    I've already (made and) done another exercise that finds all the prime numbers between 3 and "n" (value given by user) and memorizes them in a "list" of structures; then frees all the allocated memory through the "free" function, but I get absolutely no errors, there. Argh!! >.<
    The "good side" is that it finds all the prime numbers between 3 and 40.000.000 in about 14 seconds. (Intel i7 920 @ 4.00GHz)
    The "bad side" is that it's written in a single block of code (awful!!), while I'd like to separate each routine in a different header file, but first I want to be sure I'm able to pass data safely between separate functions.

    I guess this error has something to do with passing the pointer to another function, but I cant understand how.

    Please, help!! =|


    PS: about the address I "return" from the "pass_struct" function and that I assign to "oggetto1", I've also re-written it to return absolutely nothing and not assign it to "oggetto1", but the error still happens.
    Just to be clear:
    - the function call would be simply "struct_pass(oggetto1);"
    - at the end of the "struct_pass" function there would be a simple "return 0;"

    PPS: I'm using "QT Creator" ver. 2.4.1, as compiler
    Last edited by Spiegel; 12-26-2012 at 10:41 AM. Reason: PPS:

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Don't do this:
    Code:
    unsigned long secondary();
     
    int pass_struct ();
    Use declarations that are actually prototypes, e.g.,
    Code:
    unsigned long secondary(unsigned  long uno, unsigned  long due);
    
    int pass_struct(struct test * pointer);
    Next, this is not standard:
    Code:
    #include <malloc.h>
    standard is:
    Code:
    #include <stdlib.h>
    This is wrong:
    Code:
    oggetto1 = malloc(sizeof(oggetto1));
    it should be:
    Code:
    oggetto1 = malloc(sizeof(*oggetto1));
    since you want to allocate space for what the pointer points to.

    EDIT:
    Another problem is that pass_struct returns an int, but you actually return a pointer.
    Last edited by laserlight; 12-26-2012 at 10:49 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14

    Red face

    Quote Originally Posted by laserlight View Post
    Don't do this:
    Code:
    unsigned long secondary();
     
    int pass_struct ();
    Use declarations that are actually prototypes, e.g.,
    Code:
    unsigned long secondary(unsigned  long uno, unsigned  long due);
    
    int pass_struct(struct test * pointer);
    Next, this is not standard:
    Code:
    #include <malloc.h>
    standard is:
    Code:
    #include <stdlib.h>
    This is wrong:
    Code:
    oggetto1 = malloc(sizeof(oggetto1));
    it should be:
    Code:
    oggetto1 = malloc(sizeof(*oggetto1));
    since you want to allocate space for what the pointer points to.

    I've done everything you said and now it works!! Happy! ^.^

    I've checked the "sizeof" of "oggetto1" and "*oggetto1" and you're right, they're different.
    I'm an idiot, I've taken the size of the "int" address, instead of the structure at which it points!! ^^'

    Actually, from the lists exercise, I remember using the "typedef" of the structure type itself, to set a "sizeof".
    To be clear, in this exercise it would look like:
    Code:
    typedef struct test test_tpdef;
    test_tpdef * oggetto1;
    oggetto1 = malloc(sizeof(test_tpdef));
    Would it be a wrong method for any reason? =o
    I've checked the "sizeof" and it's ok, still 12 words (4 words * 3 int's).

    I've also written full declarations, instead of those bare prototypes I used before, but what's the difference?
    Why a full declaration, instead of a simplified one? What problems could it bring to? =|


    Thanks a LOT for your help!!! ^o^

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Spiegel
    Actually, from the lists exercise, I remember using the "typedef" of the structure type itself, to set a "sizeof".
    You could do that, or you could use sizeof(struct test), but sizeof(*oggetto1) is better since it would be correct even if the type of oggetto1 changes.

    Quote Originally Posted by Spiegel
    I've also written full declarations, instead of those bare prototypes I used before, but what's the difference?
    Why a full declaration, instead of a simplified one? What problems could it bring to?
    If you make a mistake when calling the function by passing arguments of the wrong type or a wrong number of arguments, the compiler is likely to warn you if you declare with a prototype. But if you declare without specifying the number and type of the parameters, then there will likely be no such warning.

    By the way, did you fix the problem with the return type of pass_struct?

    Quote Originally Posted by Spiegel
    Thanks a LOT for your help!
    You're welcome
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14

    Smile

    Quote Originally Posted by laserlight View Post
    [....]

    If you make a mistake when calling the function by passing arguments of the wrong type or a wrong number of arguments, the compiler is likely to warn you if you declare with a prototype. But if you declare without specifying the number and type of the parameters, then there will likely be no such warning.

    By the way, did you fix the problem with the return type of pass_struct?


    You're welcome

    Got the point with the full prototype of a function and sounds reasonable. Will always do.

    Ehm. "Problem" with the return type of pass_struct?
    No problem, just useless data passing for and back. ^^
    Before it was:
    Code:
    //in main
    oggetto1 = pass_struct(oggetto1);
    //and in pass_struct
    return pointer;
    But this is useless, as I save the result of the pass_struct function inside the structure itself; so now it is:
    Code:
    //in main
    pass_struct(oggetto1);
    //and in pass_struct
    return 0;

  6. #6
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    the prototypes are there for what laserlight said. As well another usage is so that your compiler knows exactly how much space to allocate based on the types you give as arguments. If you don't want to give actual identifiers in your prototypes you can simply specify the types like
    Code:
    unsigned long secondary (unsigned  long, unsigned  long);
    If you don't want to write the prototypes at all that's fine as well but you will have to include the full function definition BEFORE main() like so
    Code:
    void pass_struct (struct test * pointer){
        pointer->prodotto = pointer->numero1 * pointer->numero2;
    }
    also notice i changed the return type to pass_struct() and removed the return statement. Pointers allow you to go to the address of the actual 'object' and manipulate it so you don't need to use the return statment as you did. That's the whole point
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by caroundw5h
    As well another usage is so that your compiler knows exactly how much space to allocate based on the types you give as arguments.
    I believe the compiler will know that either way when it reaches the function definition.

    Quote Originally Posted by caroundw5h
    If you don't want to give actual identifiers in your prototypes you can simply specify the types like
    Don't do that: the parameter names are useful to document the parameters. Granted, they are not necessarily the same names as those used in the function definition, but they otherwise provide useful context.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14
    Quote Originally Posted by caroundw5h View Post
    the prototypes are there for what laserlight said. As well another usage is so that your compiler knows exactly how much space to allocate based on the types you give as arguments. If you don't want to give actual identifiers in your prototypes you can simply specify the types like
    Code:
    unsigned long secondary (unsigned  long, unsigned  long);
    If you don't want to write the prototypes at all that's fine as well but you will have to include the full function definition BEFORE main() like so
    Code:
    void pass_struct (struct test * pointer){
        pointer->prodotto = pointer->numero1 * pointer->numero2;
    }
    also notice i changed the return type to pass_struct() and removed the return statement. Pointers allow you to go to the address of the actual 'object' and manipulate it so you don't need to use the return statment as you did. That's the whole point


    Yeah, I know I can just write down the whole function without any prototype, but I hate having full spans of code BEFORE main.
    Anyway I think I'll follow laserlight's suggestion: all or nothing. =)

    And you're right, I forgot to change the return type, silly me!! >.<

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by Spiegel View Post
    Yeah, I know I can just write down the whole function without any prototype, but I hate having full spans of code BEFORE main.
    Anyway I think I'll follow laserlight's suggestion: all or nothing. =)

    And you're right, I forgot to change the return type, silly me!! >.<
    Then put the stuff in a header file.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  10. #10
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14

    Cool

    Quote Originally Posted by stahta01 View Post
    Then put the stuff in a header file.

    Tim S.
    This is just a test project, just to learn and explore specific features.

    I needed to learn this in order to implement it in another exercise I'm doing:
    - given two rational numbers, perform sum, subtraction, multiplication and division.

    This exercise alone involves:
    - finding prime numbers
    - selecting prime factors
    - storing prime factors in a list of structures
    - passing data and structures' pointers to other functions
    - making and including header files
    - problem solving that involve mathematical formulas (simple ones)

    Just building a time-saving routine to find prime numbers took me some days (since my math knowledge is embarassingly close to zero) -.-'

  11. #11
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    i am surprised, the classes i have taken required up to calc before you were even allowed to start programming....

  12. #12
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14

    Smile

    Quote Originally Posted by Crossfire View Post
    i am surprised, the classes i have taken required up to calc before you were even allowed to start programming....
    I'm not sure what you mean with "required up to calc", but I'm learning from a friend who is studying at the university.

    I have a high-school diploma in accounting and programming, but the kind of languages and "situations" I've been taught in that school are ridiculous.
    Thus, now I'm trying to learn something better, more powerful and more useful. I will lack real-world applications experience, but at least I'll understand and have chances to improve.
    I'd LOVE to have a chance to improve through experience in a real work place, but this is not an economical situation where companies invest on inexperienced people and make them grow.

    So here we are, with me asking silly questions and inventing myself some exercises to better understand things and to improve my capabilities. ^^
    Last edited by Spiegel; 12-28-2012 at 07:36 AM. Reason: missing copula

  13. #13
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    So here we are, with me asking silly questions and inventing myself some exercises to better understand things and to improve my capabilities.
    it is good to keep reaching ahead - and it is good you want to give yourself problems that interest you, bear in mind do this with restraint in order to properly gain as you go along - we sometimes see people that clearly have zero programming skill asking

    'how do i make this satellite controller for my new GPRS mapping program that i will make into an online multiplay game'

    haha, well nearly as bad as that anyway!
    Last edited by rogster001; 12-28-2012 at 11:09 AM.
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  14. #14
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14
    If anybody's still following this thread, I'd like to ask a question that is not important enough to deserve a new thread itself.

    The question is: is it just the compiler I'm using, or it's an official C rule, that I cant use "_" for "typedef" names?

    For instance: I had set a structure and then declared a typedef with that same structure to use it as a type of data more easily. The reason of this was that I had to declare several pointers of the same struct type, so I preferred to make it simpler by reducing the declaration to a neat "type * variable" instead of "struct str_name * variable".
    The name given to this typedef was something like "abc_def" and I was getting an error about something like an "incomplete statement". Banged my head really hard for quite a while, before trying to change the typedef name by taking out the freaking "_". After that, everything worked great.

    So, what is it? A rule I didnt know about or is it my compiler that's a bit picky?

    It's just for the "typedef", I have no errors of sort from any other declaration. Even the structure itself had a "_" in the name.... =p


    Thank you for dedicating me so much of your time. ^^


    PS: I'm using "QT Creator" as my "pseudo-teacher" told me to, so that we could compare methods and GUI controls more easily.

  15. #15
    Registered User Spiegel's Avatar
    Join Date
    Jul 2012
    Location
    Italy
    Posts
    14
    Quote Originally Posted by rogster001 View Post
    [....] we sometimes see people that clearly have zero programming skill asking

    'how do i make this satellite controller for my new GPRS mapping program that i will make into an online multiplay game'

    haha, well nearly as bad as that anyway!
    Yeah, I've seen that kind of questions myself. ^^
    Honestly, I felt so frightened by the level of those questions, that I thought "I could never learn C/C++, if that's the average level for a programmer!!" XD

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to properly free a pointer and its allocated memory
    By yuzhangoscar in forum C Programming
    Replies: 2
    Last Post: 09-16-2008, 06:26 AM
  2. Can you free memory allocated by a std::string?
    By BrianK in forum C++ Programming
    Replies: 17
    Last Post: 05-15-2008, 11:57 AM
  3. Malloc - Free giving double free or corruption error
    By andrew.bolster in forum C Programming
    Replies: 2
    Last Post: 11-02-2007, 06:22 AM
  4. Will free() clean up this allocated memory?
    By simguy in forum C Programming
    Replies: 3
    Last Post: 01-18-2007, 05:21 PM
  5. free allocated memory on interrupts
    By scrappy in forum C Programming
    Replies: 4
    Last Post: 02-20-2004, 11:13 AM

Tags for this Thread