Thread: Uninitialised value was created by a stack allocation --geting desperate!

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

    Uninitialised value was created by a stack allocation --geting desperate!

    Hello!

    Like written in the topic, I get this valgrind error message on a strange line of code, and after spending hours trying to figure out what is the problem I have to ask you more experienced programmers!

    So I will keep my example as short as possible:

    Code:
    test *test_struct;
    int test_num = 2;
    int test_i;
    /*my structure test is just an array with two entries*/
    test_struct = malloc(sizeof(test)* test_num);
    
    
    
    /*now I change the the test_num by a method, but it is 100% always >0, the method just increases the number*/
    
    do_something(&test_num);
    
    /*Now I call my method, where I give a copy of test_num as a parameter*/
    
    my_method(test_struct, test_num);
    }
    And the error message occurs at the line where my method is defined, specifically at the line where test_num is:

    Code:
    void my_method(test *array_struct, 
    int test_num) { <===== here is the error message occurring
    }
    And of course for every line where I use test_num i get an error message!
    Does someone have a clue what am I doing wrong at this point :S?????

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Post the code of the smallest and simplest compilable program based on your program for which Valgrind complains about this.
    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
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    I believe the error is because you allocate test_num structs to store in test_struct. Then you increment test_num, and (possibly -- I can't tell without seeing do_something and my_method) use that as some sort of array length in my_method. That means you allocated test_struct[0] and test_struct[1], but may be trying to access test_struct[3], test_struct[4], etc, which don't exist. test_struct[x] where x >= 3 are likely the "uninitialized values".

    That's only a guess however, since you provided so little code. We appreciate you trying to keep it brief, but it's hard to debug as-is.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    I'm only guessing here, but it looks to me like you're using test_num to tell my_method how many elements are pointed to by test_struct. If that is the case, then I'd say that this program is dangerous, because do_something is modifying test_num before you pass it to my_method, but after you allocate the array. Changing the value of test_num does not change the size of the array that has already been allocated. It's not as if you're assigning a formula to test_struct, where modifying its inputs implicitly modifies its outputs. It happens in sequence. On line 5, the array is allocated. Nothing you do after that can change its size, short of freeing the memory and allocating new. These things must be done explicitly.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Dunno, if it is true then the Valgrind message sounds misleading since it says "Uninitialised value was created by a stack allocation" (emphasis mine).

    EDIT:
    Quote Originally Posted by Elkvis
    Nothing you do after that can change its size, short of freeing the memory and allocating new.
    realloc does not necessarily free the memory and allocate it anew.
    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

  6. #6
    Registered User
    Join Date
    May 2014
    Posts
    69
    Ok, let me try to put more code:

    Code:
     typedef struct test2 {
            int i;
            int j;
        } test;
    Ok here a shortcut of the do_someting:
    Code:
    void do_something(test *my_structure, int *test_num) {
    
    
       /*So here the only point where I actually use the test_num:*/
        
        if ((*test_num) == 0 || (my_structure[(*test_num)-1].i
                    + (my_structure[(*test_num)-1].j  != 100) {
    
    
                (*test_num)++;
    my_structure = realloc(sizeof(test)* test_num);
    
    
                test new_entry= {100, 0}; //some numbers, doesn't matter
                my_structure[(*test_num) - 1] = new_entry;
            } 
    }
    I call the method like in the first example, and the second one the my_method(), well I don't change test_num there, but exactly like you all supposed, I use it to now the number of entries in my array

  7. #7
    Registered User
    Join Date
    May 2014
    Posts
    69
    @Elkvis


    Yes you are right, I forgot to mention in the first post that the first method also gets an instance of the array and of course reallocates and changes it!

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I asked for a complete program because then we can be sure that you aren't leaving out something that you didn't think was important. For example, get Valgrind to comment about this program:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct test_
    {
        int n;
    } test;
    
    void do_something(int *x)
    {
        ++*x;
    }
    
    void my_method(test *array_struct, int test_num)
    {
        printf("%p %d\n", (void*)array_struct, test_num);
    }
    
    int main(void)
    {
        test *test_struct;
        int test_num = 2;
        /*my structure test is just an array with two entries*/
        test_struct = malloc(sizeof(test) * test_num);
    
        /*now I change the the test_num by a method, but it is 100% always >0, the method just increases the number*/
        do_something(&test_num);
    
        /*Now I call my method, where I give a copy of test_num as a parameter*/
        my_method(test_struct, test_num);
    
        free(test_struct);
        return 0;
    }
    According to what you described in post #1, Valgrind should be reporting the same problem, but I doubt it will.
    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

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by laserlight View Post
    realloc does not necessarily free the memory and allocate it anew.
    True enough, but conceptually, it has the same effect.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by tinchi
    Yes you are right, I forgot to mention in the first post that the first method also gets an instance of the array and of course reallocates and changes it!
    We can see this in your updated code snippet for do_something, but you obviously didn't compile it: the number of arguments to realloc is incorrect. Therefore, how do we know that your code snippet has anything at all to do with the problem reported by Valgrind? For all we know, when you edited the code, you also removed the problem, so all we are looking at is code that does not exhibit the problem. That's futile.
    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

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Ugh. Please post real code -- code that you copied and pasted correctly. Your first example was missing a parameter to do_something that is quite important in us determining what your code is doing. Your second example above is missing a couple parentheses. Who knows what other relevant information/code is missing from what you posted, making our job of helping you difficult if not impossible. You're also calling realloc incorrectly. You're missing a parameter and you can't multiply a sizeof by a pointer to int.

    Also, you have no way of updating the original test_struct pointer when you realloc my_structure in do_something(). my_structure is a copy of the pointer you passed in. You update the local copy then toss away the results. If realloc moves the pointer (it might), or fails for some reason (it might), test_struct in the calling code now points to invalid memory. You would need to pass in a double pointer, and use a temp variable to store the result of realloc so you can check for success before you overwrite *my_structure.

  12. #12
    Registered User
    Join Date
    May 2014
    Posts
    69
    Yes, you are all right I know.. I just tried to avoid copying 1000 lines of code and 4 different structures I use in my method... I have to make it shorter to get it here

  13. #13
    Registered User zub's Avatar
    Join Date
    May 2014
    Location
    Russia
    Posts
    104
    Code:
    #include <stdlib.h>     // malloc, free
    #include <stdio.h>      // printf
    #include <assert.h>     // assert
    
    
    #define SIZE(x) (sizeof(x)/sizeof(x[0]))
    #define NEW(x) ((x)malloc(sizeof(struct x)))
    
    
    typedef struct Point {
        int x;
        int y;
    } *Point;
    
    
    void Point_Update(Point const p, const int new_x, const new_y)
    {
        p->x = new_x;
        p->y = new_y;
    }
    
    
    Point Point_New(const int init_x, const int init_y)
    {
        Point new = NEW(Point);
        assert(new);
        Point_Update(new, init_x, init_y);
        return new;
    }
    
    
    void Point_Delete(const Point const point)
    {
        free(point);
    }
    
    
    void Point_Print(const Point const point)
    {
        printf("x = %d, y = %d\n", point->x, point->y);
    }
    
    
    Point Point_Search(const Point* arr, unsigned int siz, const int sum)
    {
        Point p;
        while( siz-- ) {
            p = *arr++;
            if( p->x + p->y == sum ) { return p; }
        }
        return NULL;
    }
    
    
    int main(void)
    {
        Point points[3] = {
            Point_New(1, 2),
            Point_New(1, 99),
            Point_New(100, 2)
        };
    
    
        Point found = Point_Search(points, SIZE(points), 100);
        if( found ) { Point_Update(found, 0, 100); }
    
    
        unsigned int i;
        for( i = 0; i < SIZE(points); ++i ) {
            Point_Print(points[i]);
            Point_Delete(points[i]);
        }
        return 0;
    }
    Our goals are clear, tasks are defined! Let's work, comrades! -- Nikita Khrushchev

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by zub
    Code:
    void Point_Print(const Point const point)
    {
        printf("x = %d, y = %d\n", point->x, point->y);
    }
    You do realise that a typedef is not a macro, right? You probably had a declaration equivalent to this in mind:
    Code:
    void Point_Print(const struct Point* const point)
    {
        printf("x = %d, y = %d\n", point->x, point->y);
    }
    in which case not only is the pointer named point declared const, but also what it points to. However, because you used the typedef name Point instead, having the keyword const on both sides of the type name is superfluous: either way, only the pointer named point is declared const: what it points to is still declared non-const.

    This demonstrates yet again that the practice of having pointer typedefs for non-opaque pointer types is a poor practice.
    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

  15. #15
    Registered User zub's Avatar
    Join Date
    May 2014
    Location
    Russia
    Posts
    104
    Thank you for being enlightened, you are certainly right about my assumptions. I do not know much yet in such nuances.

    This demonstrates yet again that the practice of having pointer typedefs for non-opaque pointer types is a poor practice.
    I think this style have rights to exist in some kinds of programs. Perhaps it does have its flaws, but it can be said about any style. For example, I'm writing a program that initially wanted to build in this style. It turned out that it is redundant. Instead, I did support for arrays, orgranized similar to C-strings (some special number signals the end of the array). That was enough to make program incredibly simple and clear.
    Our goals are clear, tasks are defined! Let's work, comrades! -- Nikita Khrushchev

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 08-03-2014, 10:57 PM
  2. Memory Allocation in Stack
    By aakashjohari in forum C Programming
    Replies: 9
    Last Post: 01-20-2011, 01:45 PM
  3. memory allocation on the stack
    By R.Stiltskin in forum C++ Programming
    Replies: 7
    Last Post: 04-01-2009, 12:18 PM
  4. stack-based allocation
    By eXodus31337 in forum C++ Programming
    Replies: 10
    Last Post: 01-05-2009, 11:03 PM
  5. memory allocation from stack and heap ?
    By Bargi in forum C++ Programming
    Replies: 5
    Last Post: 05-29-2008, 12:37 AM