Thread: global struct initialization

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    12

    global struct initialization

    Hi,

    I should allready know this, but sometimes i confuse myself by not knowing what the compiler does.

    So, is this safe?

    Code:
    struct JustAStruct
    {
        char *name;
        ushort period;
    };
    
    JustAStruct justastruct[4] = 
    {
        "ABC", 1234,
        "DEF", 5678
    };
    i mean, the pointer to name doesnt allocate any memory. however when running this program it doesnt complain. But question is does the compiler allocate a static space for the bytes? or do i have to do it to be safe? also.. since i am only out after 3 bytes, i tried char name[3]; and using ' ' s in the structure. but when referencing to it in the code i just got garbage.

    anyway if the above code is safe, ill continue to use it, if not, please come with some suggestions.

    Thank you

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    The compiler allocates space for string constants and you've set name to point to that space. As long as you don't try to modify the chars that it's pointing to, it's okay. BTW, to save a 3 char c-string, you need 4 bytes: one extra for the nul.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    No allocation from the heap happens. Those string literals you're using, "ABC" and "DEF" are placed in some permanent part of the program, probably where you aren't allowed to write (so, e.g., don't use strcpy if name points to one of those strings). You got garbage when using name[3] because there are actually 4 characters in the string (remember the null terminator).

    You're not quite proper on your initialization, you need an extra set of braces:
    Code:
    JustAStruct justastruct[4] = 
    {
        {"ABC", 1234},
        {"DEF", 5678},
        ...
    };
    Also I know this is just an example, but it's considered poor practice to have two things with the same name, and only different cases.

  4. #4
    Registered User
    Join Date
    Jan 2012
    Posts
    12
    Thanks!

  5. #5
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    While I understand that this topic is just for clarification, it's still virtually always bad practice to use globals, especially when they're arrays or large structs.

    EDIT: rationale:

    - Globals waste memory if they're only needed in a couple functions, but in the scope of all of them.
    - Globals are much harder to keep track of their values, as any function could indiscriminately modify them.
    - Globals can cause confusion and/or errors if they are named the same as a local variable.
    - They encourage laziness because the programmer no longer has to keep track of which variables get passed where, only relying on a big pool of variables that individual functions can selectively use.
    Last edited by memcpy; 01-14-2012 at 11:57 AM.

  6. #6
    Registered User
    Join Date
    Jan 2012
    Posts
    12
    so they're useful in other words

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by memcpy View Post
    - Globals waste memory if they're only needed in a couple functions, but in the scope of all of them.
    That depends on what you consider wasted memory.

    A global only ever takes up N space. But it always takes up that space.
    A local takes up the same N space, PLUS an additional X space per time it is passed to another function. Where X is the size of either each pointer to it that you pass, or each actual instance of said variable is passed.

    Local variables used in multiple functions actually take up MORE memory than globals - but they can potentially use that memory for a smaller amount of time. It depends at which point you begin using it.

    If we have three functions: A B and C, and the "global" is created in A, which persists for a long time, and is passed randomly between B and C; where B calls C or C calls B, or A calls B OR C, you are still using up more memory than if it was just a global.
    Quote Originally Posted by memcpy View Post
    - Globals are much harder to keep track of their values, as any function could indiscriminately modify them.
    This assumes you aren't making them constant.
    Quote Originally Posted by memcpy View Post
    - Globals can cause confusion and/or errors if they are named the same as a local variable.
    There's nothing that prevents you from making local variables with the same name:
    Code:
    for( int x = 0; x < 10; x++ )
    {
        for( int y = 0; y < 10; y++ )
        {
            int x = y + 1;
            ...
        }
    }
    Quote Originally Posted by memcpy View Post
    - They encourage laziness because the programmer no longer has to keep track of which variables get passed where, only relying on a big pool of variables that individual functions can selectively use.
    Didn't you just say you had to keep track of what you name them? That sort of contradicts your previous point.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    > Local variables used in multiple functions actually take up MORE memory than globals - but they can potentially use that memory for a smaller amount of time.
    The wasted memory only manifests when you're dealing with relatively large projects, and only a couple functions use the variable. And your second point is true as well, you're only using the memory for as long as you need with locals, forgot to say that.

    > This assumes you aren't making them constant.
    If it's truly constant, why not use a #define? Variables are just that, variables, and they're supposed to change.

    > There's nothing that prevents you from making local variables with the same name
    Exactly, and that's why I said they caused confusion and errors. It's easy to lose track of which variable you're editing if a local has the same name as a global.

    > Didn't you just say you had to keep track of what you name them? That sort of contradicts your previous point.
    Yes, I did, but it isn't relevant to what I said earlier. I said it encouraged laziness because it doesn't make the programmer keep track of what's getting passed/used where, not because of namespace issues.

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by memcpy View Post
    While I understand that this topic is just for clarification, it's still virtually always bad practice to use globals, especially when they're arrays or large structs.
    Whoa, slow down there! Nobody said anything about globals. For all we know this is being used inside a function.

    Beware of starting a flame war for something that is completely off-topic!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by memcpy View Post
    > Local variables used in multiple functions actually take up MORE memory than globals - but they can potentially use that memory for a smaller amount of time.
    The wasted memory only manifests when you're dealing with relatively large projects, and only a couple functions use the variable.
    No, the wasted memory occurs always. Creating a local variable plus creating a value pass of it or a pointer to it is more memory than creating a single global variable. It doesn't matter how short of a time you have the local copy. The local will always take up more space if you ever use it in more than a single function call than having a single global instance would.

    There's no way around it. For its lifecycle, it consumes more memory than a single global instance. Now it's lifecycle may be much shorter, but that doesn't change the fact that it takes up more memory to handle it locally.

    I'm not saying globals are better. But they do take up less memory for their existence than local passing does.
    Quote Originally Posted by memcpy View Post
    > This assumes you aren't making them constant.
    If it's truly constant, why not use a #define? Variables are just that, variables, and they're supposed to change.
    That's silly. What's the point of the const keyword then if you should use a macro everywhere instead?


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    > Nobody said anything about globals
    Topic title..I was just pointing something out that was vaguely relevant, not trying to start a flamewar.

    > What's the point of the const keyword then if you should use a macro everywhere instead?
    From what I understand, the const is for when you pass something to a function, and the keyword declares that the function won't modify the variable. Do you mean static?

    > No, the wasted memory occurs always.
    Not necessarily. Local variables on the stack get automatically freed when the function exits, while globals last throughout the entire program, even when they're not being used. Also, I'm not certain, but doesn't a global pointer still occupy 4-8 bytes even after being freed?

  12. #12
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    The line:
    Code:
    JustAStruct justastruct[4] =
    should be

    Code:
    struct JustAStruct justastruct[4] =

  13. #13
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by memcpy View Post
    > What's the point of the const keyword then if you should use a macro everywhere instead?
    From what I understand, the const is for when you pass something to a function, and the keyword declares that the function won't modify the variable. Do you mean static?
    Nope, he means const. The meaning of const -- that the value wont change -- is true whether the variable is global, local automatic, local static or a parameter. It just tells the compiler to not allow that data to be changed. Go ahead, declare a global const int x; and try to change x's value in a function. The static keyword either makes a symbol file scope for global symbols like functions and global vars. For local vars, static makes it have a storage duration that is the lifetime of the program, like a global, but with name resolution still only in that scope, like a local. Static local vars do not disappear when the function is done.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by memcpy
    If it's truly constant, why not use a #define? Variables are just that, variables, and they're supposed to change.
    It is more of a C++ rule of thumb than a C rule of thumb because C++ has function templates that can (mostly) replace function-style macros, but: prefer the compiler to the proprocessor. In this case Meyers argues in Effective C++, 3rd Edition that if a macro name is used, "the symbolic name (...) may never be seen by compilers: it may be removed by the proprocessor before the source code ever gets to a compiler. As a result, the name (...) may not get entered into the symbol table. This can be confusing if you get an error during compilation involving the use of the constant because the error message may refer to (the value), not (the symbolic name). (...) This problem can also crop up in a symbolic debugger (...)". He also makes the point that "the preprocessor's blind substitution of the macro name (...) with (the value) could result in multiple copies of (the value) in your object code, while the use of the constant (...) should never result in more than one copy", though a compiler that performs a suitable optimisation may be able to avoid the copies anyway.
    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
    Join Date
    Jan 2012
    Posts
    12
    it looks like this has just gone far away off topic. let me just clear some things up.
    for me to use #define's for this would be out of the question. you see i use a struct with two variables. as an example i did, it could have been a struct with even more members. now how would you do that with a define and still look up another member of the struct? it wouldnt work. also i did allready got the answers that i needed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can't have Global Struct inside Global Struct
    By Pulse Cloud in forum C Programming
    Replies: 5
    Last Post: 10-05-2011, 03:41 PM
  2. Struct pointer initialization
    By pe4enka in forum C++ Programming
    Replies: 4
    Last Post: 12-06-2010, 05:16 AM
  3. Pointer Initialization Within A Struct
    By SMurf in forum C Programming
    Replies: 15
    Last Post: 02-09-2009, 11:27 AM
  4. Struct Initialization
    By carrotcake1029 in forum C Programming
    Replies: 5
    Last Post: 05-06-2008, 02:27 PM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM