Thread: How to set an array slot to NULL

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    101

    How to set an array slot to NULL

    I guess this is a really basic question and I've researched but couldn't find my answer.

    The thing I want to set all the slots of an array of stucts to NULL.

    If I do this
    Code:
    shMem->array[i] = NULL;
    I get
    Code:
    error: incompatible types in assignment
    So how can I set the slots to NULL so I can know they aren't used?

    Thanks in advance.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And what type are the elements of array ?

    NULL in C is a pointer with the value 0 (or something corresponding to that in some implementations)...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    101
    It's an array of tasks in a struct for shared memory
    Code:
    typedef struct _task{
    	char path [MAX_PATH_LEN];
    	char thread_id[MAX_PATH_LEN];
    	char op;
    	struct _task* ptr;
    }task;
    
    typedef struct _sharedMem{
    	task array [50];
    	int lastIn;
    	int numTasks;
    	sem_t mutex;
    }sharedMem;
    I see so as it's a pointer you can really equal it to an array slot.

    So the alternative would be to set the struct in that slot so that I know that it's not being use? I never have a problem just calling an attribute of an object in an array?

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Ehm, are you actually storing this in shared memory? If so,
    Code:
    	struct _task* ptr;
    is a dangerous construct, as if we assume it points within the shared memory, you can not be guaranteed that the shared memory is at the same location in different processes - the OS may have used that virtual address for something else by the time you open the shared memory. Use an offset from the start of your shared memory instead of a pointer, the make it a pointer by adding it to the shared memory base address when you need to get to it.

    You obviously can't use NULL to assign to a struct, so yes, you will need to put some value somewhere that indicates "not in use" within your task struct.

    Also, using names that start with _ is a bad idea in general, as such names are reserved for the compiler/C library implementors.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    The easy answer is:
    Code:
    memset( array, '\0', sizeof( array ) );
    But that may not always be the right way to do it (i.e. your structs might have memory that needs to be free'd first).
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by kotoko View Post
    It's an array of tasks in a struct for shared memory
    Code:
    typedef struct _task{
    	char path [MAX_PATH_LEN];
    	char thread_id[MAX_PATH_LEN];
    	char op;
    	struct _task* ptr;
    }task;
    
    typedef struct _sharedMem{
    	task array [50];
    	int lastIn;
    	int numTasks;
    	sem_t mutex;
    }sharedMem;
    I see so as it's a pointer you can really equal it to an array slot.

    So the alternative would be to set the struct in that slot so that I know that it's not being use? I never have a problem just calling an attribute of an object in an array?
    Look at the memset() call to initialize the array of task structs or a particular element thereof to NULL.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by itCbitC View Post
    Look at the memset() call to initialize the array of task structs or a particular element thereof to NULL.
    Well, you can set all elements to zero - if some implementation of compiler decides that NULL is actually internally represented by something other than zero, you may be in trouble.

    Of course, as discussed above, you should not have pointers in shared memory, so storing NULL anywhere within a shared memory block is unlikely to be the RIGHT thing to do.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    101
    Thanks for the heads up with the pointer problem, I'm adapting from a threads program so I didn't notice that yet. I guess I'll just substitute that with the index of the array, that might be simpler.

    you will need to put some value somewhere that indicates "not in use" within your task struct.
    My problem with this is that I'm not sure what happens when you do a shMem->array[i].path to something that hasn't been used. but I guess it's fine and I'm, being silly.

    Also, using names that start with _ is a bad idea in general, as such names are reserved for the compiler/C library implementors.
    I didn't know about that, thanks.

  9. #9
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by matsp View Post
    Well, you can set all elements to zero - if some implementation of compiler decides that NULL is actually internally represented by something other than zero, you may be in trouble.
    IMHO that would be decided internally by the machine's native character set ie ASCII or EBCDIC instead of by the compiler.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by itCbitC View Post
    IMHO that would be decided internally by the machine's native character set ie ASCII or EBCDIC instead of by the compiler.
    Ehm, that is a different NULL - NULL here, in C, is [usually]
    Code:
    #define NULL ((void *) 0)
    So whilst that may well cause the memory to be filled with the zero value, it is not guaranteed that
    Code:
    int *ptr = NULL;
    actually stores a zero value in the memory occupied by the variable p - the compiler & C library MAY decide that NULL is actually -1 - it should still behave AS IF NULL is zero if you do "if (p == 0) ... ", but the actual machine code would compare p with -1. [Just as an example, of course].

    Admittedly, I'm picking holes by pedantery, but if I'm sure someone else would shove the same argument down my throat if I made such a suggestion.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by matsp View Post
    Ehm, that is a different NULL - NULL here, in C, is [usually]
    Code:
    #define NULL ((void *) 0)
    Correct as the NULL symbol can be redefined elsewhere thereby taking precedence over its definition in the C library include files.
    Quote Originally Posted by matsp View Post
    So whilst that may well cause the memory to be filled with the zero value, it is not guaranteed that
    Code:
    int *ptr = NULL;
    actually stores a zero value in the memory occupied by the variable p - the compiler & C library MAY decide that NULL is actually -1 - it should still behave AS IF NULL is zero if you do "if (p == 0) ... ", but the actual machine code would compare p with -1. [Just as an example, of course].
    I concur
    Quote Originally Posted by matsp View Post
    Admittedly, I'm picking holes by pedantery, but if I'm sure someone else would shove the same argument down my throat if I made such a suggestion.

    --
    Mats
    #define NULL ((void *)0L) now that's pedantic
    Last edited by itCbitC; 01-06-2009 at 11:35 AM.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    #define NULL ((void *)0L) now that's pedantic
    How is that pedantic?
    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

  13. #13
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    How is that pedantic?
    and why not? go figure

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    and why not?
    Because section 6.3.2.3 paragraph 3 of the 1999 edition of the C Standard states:
    An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.
    with the note:
    The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant
    For a long int, the value 0 can be expressed by the constant 0L, but long int is not a pointer type anyway. My point is that to be pedantic, the standard allows both (void*)0 and (void*)0L, so suggesting that (void*)0L is pedantic in the face of the previous expression is... not being pedantic.
    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
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    Because section 6.3.2.3 paragraph 3 of the 1999 edition of the C Standard states:

    with the note:

    For a long int, the value 0 can be expressed by the constant 0L, but long int is not a pointer type anyway. My point is that to be pedantic, the standard allows both (void*)0 and (void*)0L, so suggesting that (void*)0L is pedantic in the face of the previous expression is... not being pedantic.
    agree that long int 0L by itself is not a pointer and by the same argument neither is int 0L unless cast.
    imo only difference is the precision and pedantic in this context refers purely to the degree of precision.
    Last edited by itCbitC; 01-06-2009 at 01:26 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help Debugging my AVL tree program.
    By Nextstopearth in forum C Programming
    Replies: 2
    Last Post: 04-04-2009, 01:48 AM
  2. New string functions
    By Elysia in forum C Programming
    Replies: 11
    Last Post: 03-28-2009, 05:03 AM
  3. Replies: 10
    Last Post: 07-10-2008, 03:45 PM
  4. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM
  5. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM

Tags for this Thread