Thread: uninitialized value was created by a heap allocation, memcheck with valgrind

  1. #1
    Registered User
    Join Date
    May 2014
    Posts
    69

    uninitialized value was created by a heap allocation, memcheck with valgrind

    Hello!

    I discovered valgrind and started using it for my c code. But I get following error message at almost every malloc position, :

    ==19505== 40 errors in context 10 of 12:
    ==19505== Use of uninitialised value of size 8
    ==19505== at 0x10000416E: my_method (main.c:662)
    ==19505== by 0x10000159E: main (main.c:182)
    ==19505== Uninitialised value was created by a heap allocation
    ==19505== at 0x47F1: malloc (vg_replace_malloc.c:302)
    ==19505== by 0x100001C21: my_method (main.c:333)
    ==19505== by 0x10000159E: main (main.c:182)

    and I really don't understand what it means. I already googled it but I didn't find out what is my mistake.

    SO here i just put one example:

    Code:
    int main(int argc, char** argv) {
    
    //i declare my variables at this position
        Uint *used, *forbidden_jumps, *forbidden_jumpsV,
                *forbidden_jump;
    
    /*now i want to allocate one of them, this is my line 333 from the error message*/
    
    //a_num is set during the execution of the program,
    ALLOC(used, Uint, a_num);
    
    }
    // i defined a macro alloc which looks like this
    Code:
    #define ALLOC(P,T,S) if(((P)=(T*)malloc(sizeof(T)*(S))) == NULL) {\
    	  fprintf(stderr,"malloc failed");\
    	  exit(1);\
            }


    Is there any help page for the output of valgrind? I found it on the homepage but it is not so well-explained for my taste

  2. #2
    Registered User
    Join Date
    May 2014
    Posts
    69
    Ok or is maybe my allocation the problem? When I need a two-dimensional pointer to anything, I first allocate the first dimension, and then the second, is this wrong?

    Code:
    int i;
    int **my_array;
    
    //First allocation: (see upper post for the definition of ALLOC)
    ALLOC(my_array, int*, 2);
    
    //now second dimension:
    for(i =0; i < 2; i++){
    
    ALLOC(my_array[i], int, 20); //so an array of 20 entries
    }

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,083
    You do not need to pass the type as a parameter since it can be deduced by the destination pointer type. Hence, you could have written ALLOC as:
    Code:
    #define ALLOC(result, num_elements) do {\
        if (((result) = malloc(sizeof(*(result)) * (num_elements))) == NULL) {\
            fprintf(stderr, "malloc failed");\
            exit(EXIT_FAILURE);\
        }\
    } while (0)
    Anyway, I suggest that you compile and check a simplified program with Valgrind:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ALLOC(P, T, S) if (((P) = (T*)malloc(sizeof(T) * (S))) == NULL) {\
        fprintf(stderr, "malloc failed");\
        exit(1);\
    }
    
    typedef unsigned int Uint;
    
    int main(void) {
        Uint *used;
        Uint a_num = 5;
    
        ALLOC(used, Uint, a_num);
        free(used);
        return 0;
    }
    What does Valgrind report?
    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

  4. #4
    Registered User
    Join Date
    May 2014
    Posts
    69
    Ok, with this example valgrind shows exactly 0 errors, this is strange :S

  5. #5
    Registered User
    Join Date
    May 2014
    Posts
    69
    What about my second post? Do I allocate correctly??

    I think I have noticed something, can it be that if I allocate an array, that I always have directly to set the entries to some standard value, so 0 for ints, because in my method sometimes they are set in an -if- part so maybe this is one problem?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,083
    Quote Originally Posted by tinchi
    What about my second post? Do I allocate correctly??
    It looks okay.

    Quote Originally Posted by tinchi
    I think I have noticed something, can it be that if I allocate an array, that I always have directly to set the entries to some standard value, so 0 for ints, because in my method sometimes they are set in an -if- part so maybe this is one problem?
    No, this is not necessarily a problem, though providing a sensible initial value is a Good Thing. You probably have a bug such that you did not provide an initial value, and yet you used the object. Notice:
    Code:
    ==19505== Use of uninitialised value of size 8
    ==19505== Uninitialised value was created by a heap allocation
    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

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    malloc() doesn't initialise the memory it provides. valgrind will complain if any any path through your program is executed in which that memory is used without being initialised.

    Following your code
    Code:
    int i;
    int **my_array;
     
    //First allocation: (see upper post for the definition of ALLOC)
    ALLOC(my_array, int*, 2);
     
    //now second dimension:
    for(i =0; i < 2; i++){
     
    ALLOC(my_array[i], int, 20); //so an array of 20 entries
    }
    the individual my_array[i][j] (i = 0-1, j = 0-19) are uninitialised. My guess is that some subsequent code accesses such values (e.g. reads their value, compares their value with something) before initialising them.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Registered User
    Join Date
    May 2014
    Posts
    69
    Ok, thank you both really much for your suggestions.
    I will check where I use objects I forgot not initialise, strange that the code compiles if this is the case

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by tinchi View Post
    I will check where I use objects I forgot not initialise, strange that the code compiles if this is the case
    Not strange at all.

    Using uninitialised variables results in undefined behavior according to the standard. That means, among other things, that a compiler is not required to detect such problems, and is not required to do anything in particular (useful or otherwise) if it does.

    Technically, there are particular cases (variable defined but uninitialised in one compilation unit, value of that variable accessed in another compilation unit) that a C compiler cannot necessarily even detect, let alone report a compilation error. The only way that could be eliminated would be to completely change C's compilation model - in particular, to eliminate separate compilation. That would make C compilers more expensive (more code needed for analysis that programmers often don't need) and - for large programs with many compilation units - would increase build times by several orders of magnitude.

    You could also make use of some additional tools, such as static analysers. Such tools tend to be expensive but they do pick up problems that will not be detected by a stock-standard C compiler. Some C compilers do some forms of static analysis (which is why some compilers give warnings, if they are appropriately configured, about uninitialised variables). But C compilers are not required to do this and, even if they do, there are still problems they cannot detect.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. valgrind and "uninitialized" member values
    By MK27 in forum C++ Programming
    Replies: 6
    Last Post: 04-20-2011, 11:14 AM
  2. Replies: 5
    Last Post: 01-15-2011, 12:31 PM
  3. Memory Allocation Error - /w Valgrind Output
    By Ggregagnew in forum C Programming
    Replies: 5
    Last Post: 12-02-2010, 04:02 PM
  4. Replies: 4
    Last Post: 06-20-2007, 06:33 AM
  5. about heap allocation
    By sawer in forum C++ Programming
    Replies: 5
    Last Post: 04-15-2006, 11:09 AM