Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0

    Declarations of structs, and arrays seem to be overlapping in memory..?!


    New to this list (first post), and relatively new to C, so hi
    everyone...

    If anyone can help me with this I'll be most grateful... The following
    code is from a rather elaborate (for me) program I'm writing (hence
    all the meaningles [to you no doubt] variable names and so on), but
    I've narrowed the problem down to these snippets. Just to make sure,
    I created this code alone (new file separate to my larger project) and
    the problems are still exhibiting themselves. Here's the code:

    -------------------------------------------------
    #include <stdio.h>


    typedef struct DateInts {
    int day, month, year;
    } date_ints;

    typedef struct InputParameters {
    date_ints dateStart, dateEnd, dateToPredict;
    } input_parameters;

    int main (int argc, const char * argv[]) {

    input_parameters parameters;

    printf ("parameters.dateStart = %X, %X, %X\n",
    &(parameters.dateStart.day),
    &(parameters.dateStart.month),
    &(parameters.dateStart.year)
    );
    printf ("parameters.dateEnd = %X, %X, %X\n",
    &(parameters.dateEnd.day),
    &(parameters.dateEnd.month),
    &(parameters.dateEnd.year)
    );
    printf ("parameters.dateToPredict = %X, %X, %X\n",
    &(parameters.dateStart.day),
    &(parameters.dateStart.month),
    &(parameters.dateStart.year)
    );

    int weekCount = 6;//CountWeeks (parameters);
    printf ("weekCount = %d\n", weekCount);
    date_ints weekDates[2][weekCount];

    int symbolCountCompare; // = CountSymbolNumbers
    (fileNameCompare);

    printf ("symbolCountCompare = %d @ %X\n", symbolCountCompare,
    &symbolCountCompare);
    printf ("&weekDates[2][5] = %X, %X, %X\n",
    &(weekDates[2][5].day),
    &(weekDates[2][5].month),
    &(weekDates[2][5].year));

    return 0;
    }
    -------------------------------------

    I hope that's come out ok.

    I've put in all the printf statements to illustrate that certain
    variables are overlapping in memory. It seems to be consistent in
    this code to the code in my bigger project, even though that's got a
    lot of other stuff going on as well.

    Note I haven't initialized most of them, but please note that when I
    do it doesn't change anything. As I understand it the memory is
    allocated at declaration time, so initialization should make no
    difference I believe.

    The above code exhibits two problems (at least on my machine - a
    PowerMac G4, dual 1.25GHz, Mac OS 10.2.6, Apple's Project Builder 2.1
    or the built in unix Terminal):

    1. the memory location of symbolCountCompare and weekDates[2][5].month
    are both the same.
    2. the memory location of each of the members of the
    paramaters.dateStart and parameters.dateToPredict are the same.

    I accept it's possible that this may be different on other machines,
    so would any of you be willing to compile this on your machines and
    let me know if you get different or the same results?

    I just can't for the life of me figure out why this would be
    happening. Sure this is perhaps complex data structures, but at the
    end of the day, most of the above code is just variable declarations.
    Why on earth are they overlapping?

    I'm wondering if I've misunderstood how structs and arrays handle
    memory. I admit I don't have a very good grasp of pointers and such -
    I tend to try to avoid them as much as I can. So if the answer to all
    this is really obvious and I've missed it, I apologise.

    Regards,
    David.
  2. #2
  3. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    27
    >> date_ints weekDates[2][weekCount];

    AFAIK you can't do this. Have to declare the array a constant size or dynamically allocate memory for it.

    >>2. the memory location of each of the members of the
    paramaters.dateStart and parameters.dateToPredict are the same.

    not in my MSVC.Net complier.
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  4. #3
  5. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    243
    Please enclode your code in "code" tags (see http://forums.devshed.com/misc.php?action=bbcode&s=).

    You can't allocate a static array with a variable, you have to use new (in the case of C++, or malloc in the case of C, I used C++ in the example). I am not sure why your code would have compiled, but mine does on Visual C++ 6.0 (after I commented out the reference to fileNameCompare).

    If this doesn't help, please provide more information.

    Code:
    #include <stdio.h> 
    
    
    typedef struct DateInts { 
        int day, month, year; 
    } date_ints; 
    
    typedef struct InputParameters { 
        date_ints dateStart, dateEnd, dateToPredict; 
    } input_parameters; 
    
    int main (int argc, const char * argv[]) { 
        int i;
    
        input_parameters parameters; 
    
        printf ("parameters.dateStart = %X, %X, %X\n", 
                            &(parameters.dateStart.day), 
                            &(parameters.dateStart.month), 
                            &(parameters.dateStart.year) 
        ); 
        printf ("parameters.dateEnd = %X, %X, %X\n", 
                            &(parameters.dateEnd.day), 
                            &(parameters.dateEnd.month), 
                            &(parameters.dateEnd.year) 
        ); 
        printf ("parameters.dateToPredict = %X, %X, %X\n", 
                            &(parameters.dateStart.day), 
                            &(parameters.dateStart.month), 
                            &(parameters.dateStart.year) 
        ); 
    
        int weekCount = 6;//CountWeeks (parameters); 
        printf ("weekCount = %d\n", weekCount); 
        date_ints *weekDates[2]; 
        for (i=0; i<2; i++){
            weekDates[i] = new date_ints[weekCount];
        }
    
        int symbolCountCompare; // = CountSymbolNumbers 
    //    (fileNameCompare); 
    
        printf ("symbolCountCompare = %d @ %X\n", symbolCountCompare, 
                            &symbolCountCompare); 
        printf ("&weekDates[2][5] = %X, %X, %X\n", 
                            &(weekDates[2][5].day), 
                            &(weekDates[2][5].month), 
                            &(weekDates[2][5].year)); 
    
        for (i=0; i<2; i++){
            delete [] weekDates[i];
        }
        return 0; 
    }

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0
    ok... thanks to those who have responded. Sorry about the terribly formatted code. I've never used these tag things before in my life, so i'm having a bit of trouble getting my head around them.

    My apologies too about those meaningless comments - they were pieces I was commenting out when I was testing it in my IDE, but forgot to remove them when posting.

    Anyway...

    Now one or two of you have noted that I can't declare an array using a variable. That's a bit disappointing, since I was sure I could, but if not, so be it.

    However, that still leaves me wondering why the first bit doesn't work...

    So yeah... let's try that again, with only this bit...

    Code:
    #include <stdio.h>
    
    
    typedef struct DateInts {
        int day, month, year;
    } date_ints;
    
    typedef struct InputParameters {
        date_ints dateStart, dateEnd, dateToPredict;
    } input_parameters;
    
    int main (int argc, const char * argv[]) {
    
        input_parameters parameters;
    
        printf ("parameters.dateStart     = %X, %X, %X\n",
                &(parameters.dateStart.day),
                &(parameters.dateStart.month),
                &(parameters.dateStart.year)
                );
        printf ("parameters.dateEnd       = %X, %X, %X\n",
                &(parameters.dateEnd.day),
                &(parameters.dateEnd.month),
                &(parameters.dateEnd.year)
                );
        printf ("parameters.dateToPredict = %X, %X, %X\n",
                &(parameters.dateStart.day),
                &(parameters.dateStart.month),
                &(parameters.dateStart.year)
                );
    
        return 0;
    }
    On my Mac, the output from this is:

    ----------------
    parameters.dateStart = BFFFFD00, BFFFFD04, BFFFFD08
    parameters.dateEnd = BFFFFD0C, BFFFFD10, BFFFFD14
    parameters.dateToPredict = BFFFFD00, BFFFFD04, BFFFFD08
    ----------------

    Note the addresses on the first and last lines are the same!

    Any ideas on that one?

    Thanks again.
    David
  8. #5
  9. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    243
    Yea, I know why the memory locations are exactly the same...

    They ARE exactly the same variables!

    You have a 'typo' in your (undoubably copied and pasted) code.

    Try this:

    Code:
    #include <stdio.h> 
    
    
    typedef struct DateInts { 
        int day, month, year; 
    } date_ints; 
    
    typedef struct InputParameters { 
        date_ints dateStart, dateEnd, dateToPredict; 
    } input_parameters; 
    
    int main (int argc, const char * argv[]) { 
        int i;
    
        input_parameters parameters; 
    
        printf ("parameters.dateStart = %X, %X, %X\n", 
                            &(parameters.dateStart.day), 
                            &(parameters.dateStart.month), 
                            &(parameters.dateStart.year) 
        ); 
        printf ("parameters.dateEnd = %X, %X, %X\n", 
                            &(parameters.dateEnd.day), 
                            &(parameters.dateEnd.month), 
                            &(parameters.dateEnd.year) 
        ); 
        printf ("parameters.dateToPredict = %X, %X, %X\n", 
                            &(parameters.dateToPredict.day), 
                            &(parameters.dateToPredict.month), 
                            &(parameters.dateToPredict.year) 
        ); 
        return 0; 
    }
    As for why this 'works' and the array declaration with variables doesn't is the difference between compile time and run time. If the compiler can figure out what the size of a variable is (arrays are variables) then it can allocate memory at compile time (it can be more complex than this, but this is the gist). Just because you have assigned a variable (weekCount in this case) with a number at compile time doesn't mean that that number will still be the same at run time, so the compiler can't make a determination. If you use #defines (meaning they are aliases for fixed values) then the compiler knows exactly what you are trying to do and will create the memory for you.

    If you are visiting C from another language that is free with these sorts of things, this is the price you pay for speed. The compiler does a tremendous amount of work ahead of time so that during run time only the minimal amount of work has to be done. Interpreted languages (such as Perl and I presume PHP) do the 'compiling' at the time of execution and can therefore examine your actual runtime variables. C/C++ doesn't do that.

    Does this explanation make sense?

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  10. #6
  11. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0
    Originally posted by mitakeet
    Yea, I know why the memory locations are exactly the same...

    They ARE exactly the same variables!
    Oh Duh! Ok thanks. Don't I feel like an idiot. :-)

    So I've just changed the second set of DateStart's to DateToPredict's in my code in my IDE and that bit works fine now.
    As for why this 'works' and the array declaration with variables doesn't is the difference between compile time and run time. If the compiler can figure out what the size of a variable is (arrays are variables) then it can allocate memory at compile time (it can be more complex than this, but this is the gist). Just because you have assigned a variable (weekCount in this case) with a number at compile time doesn't mean that that number will still be the same at run time, so the compiler can't make a determination. If you use #defines (meaning they are aliases for fixed values) then the compiler knows exactly what you are trying to do and will create the memory for you.

    If you are visiting C from another language that is free with these sorts of things, this is the price you pay for speed. The compiler does a tremendous amount of work ahead of time so that during run time only the minimal amount of work has to be done. Interpreted languages (such as Perl and I presume PHP) do the 'compiling' at the time of execution and can therefore examine your actual runtime variables. C/C++ doesn't do that.

    Does this explanation make sense?
    Yes perfectly. Thank you. Your detailed attention to this is most appreciated.

    So then... for my program, that array needs to be variable - not variable DURING runtime, since once it is set it will be consistent throughout the running of the program, but each time the program runs it will need to be a different size (ie. weekCount is a number read in from another file) and so will need to be declared a different size each time the program is run.

    So I take it you're saying that if that's the case, I just can't do it that way - is that it? Is this where I have to get my head around malloc, etc?

    (I'm finding the memory allocation functions difficult to get my head around. I understand the concept but how to reference it all once it's allocated is proving challenging to my brain!) :-)

    Thanks again for your explanation.

    PS. Is java another language (like Perl and PHP) that will allow what I'm trying to do?

    David.
  12. #7
  13. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    243
    Java is very much like C++, though it makes it nearly impossible to access low level information (for me, a real big problem). It is also slow, generally much slower than C++. However, it does protect you from a lot of stupid C mistakes, so it is better to learn on. The syntax is very simmiliar to C++, though just enough different so you can't port the code easily.

    In my first example I gave you some code snippets for doing the memory allocation dynamically, try this out and see how far you can get. I can help with more if you like, but give it a try first. ou can also search the forum here, I have posted other stuff along those lines.

    Don't worry about the Duh!, it happens to everyone. That is one of the best services of these types of forums, it gets a fresh pair of eyeballs (sometimes quite a few) on your problem.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  14. #8
  15. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0
    OK, so I take it, that "new dateints[weekCount]" bit and the "delete[] weekDates[i]" are both part of C++...? The problem with understanding that is I know absolutely nothing of C++! :-) Your sample code there is probably the first I've ever seen of it.

    It seems what I have to decide now, is whether I must venture out and learn C++ for this (entire program of which I've only presented a small fraction here), or will Java (which I already know a bit of, and which I have to learn anyway for other reasons) suffice?

    Certainly the ability to access low level information is of no importance to me - in fact I'd rather stay away from all that. But speed may be an issue though... Just how much slower is Java? (I understand basically that Java is partly compiled and partly interpreted hence that will hit it's speed at runtime, but I just don't know how badly it will hit MY program).

    (By the way, if you're wondering what I'm trying to do, I'm reading in large amounts of stock market data from a couple of text files downloaded from Yahoo [very large - like a few thousand lines each]. I have to read it all in, into some sort of multideminsional storage, and then compare different bits to each other and sum and average other bits, then spit all the results back out to another text file. It has to do all that within certain time limits [though not seconds. An hour or so would suffice.])

    Thank you so much for your help with all this.
  16. #9
  17. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    243
    Given your time constraints (or really, lack thereof), Java will work fine. However, I am pretty sure you will have to do the same 'new's and 'delete's as you would in C++, I don't think Java will let you do what you want (I have done some programming in Java).

    The speed difference can be significant, but if you are happy with minutes (actually, I expect Java will take care of your needs in seconds), I wouldn't worry about trying to learn C++. I work on programs that can run for days on high-end workstations, so the difference of even a few percent (not that the difference between Java and is _only_ a few percent, more like an order of magnitude) are significant to me (actually, I do most of my heavy duty work in C because C++ is significantly slower than C). A few thousand records is not a 'big'.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  18. #10
  19. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0
    Aaah yes, I see why you need the access to the low level stuff. Fair enough.

    Well sounds like Java is the way for me to go then. Actually, since I started this thread yesterday, I started looking into doing it in Java in case I was going to have to (hence my last post discussing it), and have made some small progress already.

    Since I have to learn Java anyway for other reasons, I'm glad to hear that it's probably not going to be too slow. So I guess that solves the problem (in a roundabout sort of way)!

    Well... Your prompt and detailed help is really appreciated... Thanks again! Cheers...
  20. #11
  21. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0
    Originally posted by mitakeet
    Given your time constraints (or really, lack thereof), Java will work fine. However, I am pretty sure you will have to do the same 'new's and 'delete's as you would in C++, I don't think Java will let you do what you want (I have done some programming in Java).
    Wait a second... Just after posting that last message I re-read yours...

    You "DON'T" think java will let me do it? Why do you say that? I don't mind new's and delete's - that's not an issue.

    The only issue was having to learn a whole new language (C++) only for this program.

    Either way (Java or C++) I'll have to learn a new language, the only difference is that I have to learn Java (and have already begun doing so) for other reasons anyway.

    Did I misunderstand you?
  22. #12
  23. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    243
    Nope, Java will do just fine. If you do choose to learn C++ at some point, the learning curve will be smaller because of the similiarity in syntax.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  24. #13
  25. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0
    OK Great. Well thanks again.
    Cheers!
    David.
  26. #14
  27. No Profile Picture
    status unknown
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    262
    Rep Power
    12
    Others have pointed out that you can't use a variable in an array declaration. However, variable length arrays were introduced in C99, and some compilers have permitted this as an extension for years.

    The size expression is evaluated at run-time and the array is created with the size specified, which can't be changed during the lifetime of the array but may vary each time it is created. You can use sizeof with a variable length array, and it is calculated at run-time.

    So this is (now) valid C:

    int arraySize;
    arraySize = someFunction();
    double myArray [arraySize];
    Last edited by BigBadBob; September 1st, 2003 at 02:40 PM.
  28. #15
  29. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Australia (Brisbane and Sydney)
    Posts
    11
    Rep Power
    0
    OK...
    Thanks again to mitakeet, and also now to you BigBadBob.

    BigBadBob: Does C99 allow what you've suggested with multi-dimensional arrays? or only 1-dim?

    For example, (extending yours):
    Code:
    int arraySize1, arraySize2, arraySize3;
    arraySize1 = someFunction1();
    arraySize2 = someFunction2();
    arraySize3 = someFunction3();
    double myArray [arraySize1][arraySize2][arraySize3];
    Will that work in C99?

    (I also have another question about understanding malloc etc. but it's probably worthy of another thread so I shall create one for it).

    Thanks again.
    David.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo