Thread: initializing a array of pointers

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

    initializing a array of pointers

    hello, i want to initialize an array of pointers. this is how i did it, can u tell me if it is correct?

    Code:
    //ThreadControlBlock is a struct i created
    typedef struct {
        ucontext_t context;
        char thread_name[THREAD_NAME_LEN];
        int thread_id;
        ThreadState state;
        void stack[1024];
    }ThreadControlBlock;
    
    ThreadControlBlock* ue_table[MAX_NUM_OF_THREADS];
    
    ue_table = (ThreadControlBlock*) malloc(MAX_NUM_OF_THREADS*sizeof(ThreadControlBlock);
    is this correct?

  2. #2
    Registered User
    Join Date
    Jan 2012
    Posts
    38
    btw, MAX_NUM_OF_THREADS is 10

  3. #3
    Registered User TheBigH's Avatar
    Join Date
    May 2010
    Location
    Melbourne, Australia
    Posts
    426
    Almost.

    In your declaration of ue_table in line 10, you don't need the square brackets since this will do exactly what you're doing with the malloc.

    Also it is not necessary to typecast the malloc, and many people will advise you not to do that.
    Code:
    while(!asleep) {
       sheep++;
    }

  4. #4
    Registered User
    Join Date
    Jan 2012
    Posts
    38
    thnx for the quick reply. but if i remove square brackets, then wont it be a 1D array. what i am aiming for is an array of pointers. where each element of the array is a pointer.

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    TheBihH, he said he wants an array of pointers, not an array of ThreadControlBlock's.

    If you want an array of pointers, and the size is known at compile time (e.g. not dependent on data obtained by running the program) then do everything in your code except the malloc() call. This gives you an array of MAX_NUM_OF_THREADS pointers. Note that those pointers (the elements of the array) still need to be initialised.

    If the size is not known at compile time, then ue_table needs to be a pointer to pointer
    Code:
        ThreadControlBlock **ue_table;
    and allocate memory for it like this
    Code:
       ue_table = malloc(MAX_NUM_OF_THREADS*sizeof(ThreadControlBlock *));
    Again, this leaves the elements of the array uninitialised.

    Either way, to initialise the elements of ue_table, the approach might be (if you want to set them all to NULL pointers)
    Code:
        for (i = 0; i < MAX_ NUM_OF_THREADS; ++i)
           ue_table[i] = NULL;
    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.

  6. #6
    Registered User
    Join Date
    Jan 2012
    Posts
    38
    hi, i dont what u mean by size is not known on compile time? I mean isnt what u did below the same thing as knowing the size too bcuz u know MAX_NUM_OF_THREADS:

    Code:
    
       ue_table = malloc(MAX_NUM_OF_THREADS*sizeof(ThreadControlBlock *));






  7. #7
    Registered User
    Join Date
    Jan 2012
    Posts
    38
    i think i know what u mean now, but for initialization of elements of ue_table, can i do this:

    Code:
    for (i = 0; i < MAX_ NUM_OF_THREADS; ++i)
       ue_table[i] = (ThreadControlBlock*) malloc(sizeof(ThreadControlBlock);;

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by ueg1990 View Post
    hi, i dont what u mean by size is not known on compile time?
    "Not known at compile time" means that the value can't be determined until the program is run.

    For example, if MAX_NUM_OF_THREADS is of type int and it is read like this.
    Code:
        scanf("&d", &MAX_NUM_OF_THREADS);
    the value cannot be known to the compiler.


    Quote Originally Posted by ueg1990 View Post
    I mean isnt what u did below the same thing as knowing the size too bcuz u know MAX_NUM_OF_THREADS:
    No it is not. The argument of malloc() can be known at compile time, but does not need to be.

    Note: recent C compilers support variable length arrays (a feature introduced in the C standard of 1999). However, beginners routinely misuse that feature, and you have asked a beginner's question, so I have deliberately not given an example involving VLAs.

    Quote Originally Posted by ueg1990 View Post
    i think i know what u mean now, but for initialization of elements of ue_table, can i do this:
    Code:
    for (i = 0; i < MAX_ NUM_OF_THREADS; ++i)
       ue_table[i] = (ThreadControlBlock*) malloc(sizeof(ThreadControlBlock);;
    You can. The (ThreadControlBlock *) type conversion is not needed in C though, and is generally a bad idea. If it is necessary to get your code to compiler, then you have either forgotten to #include <stdlib.h> (and your code with the conversion has undefined behaviour) or you are compiling with a C++ compiler.
    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.

  9. #9
    Registered User
    Join Date
    Jan 2012
    Posts
    38
    why is the (ThreadControlBlock *) type conversion is needed in C?? and why is it generally a bad idea??

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It is not needed in C. It is a bad idea because it hides programming errors.

    malloc() is declared in <stdlib.h> as returning a void * (aka a void pointer). A void pointer can be implicitly converted (i.e. no explicit conversion or "cast") to any other type of pointer. So sayeth the C standard.

    The problem comes if the programmer forgets to #include <stdlib.h>. The compiler therefore does not see a declaration informing it that malloc() returns void *. When code calls an undeclared function, it assumes that function returns int (and accepts a variable argument list, but that's not relevant here). Again, so sayeth the C standard. So, if you do x = malloc(some_size); where x is a pointer then, and <stdlib.h> has not been #include'd, the compiler will give an error, since an int cannot be implicitly converted to a pointer. The correct fix is to #include <stdlib.h>.

    If, instead, you use an explicit type conversion, what happens? First, the compiler assumes malloc() returns int. But you have done an explicit conversion, in your case, of that int to a (ThreadControlBlock *) so the compiler remains silent (among other things, using an explicit type conversion prevents the compiler complaining about certain invalid type conversions). You have received no errors from the compiler, so you happily proceed to compile and link your program. The linker finds malloc() (which is implemented as a function returning void *). The sequence which occurs at run time when malloc() is called is then.

    1) malloc(), as implemented, returns void *.
    2) At the call point, that void * is converted to int (since that is what the compiler assumes malloc() returns).
    3) Since you have done an explicit type conversion, that int value is converted back to a pointer (a ThreadControlBlock * in your case).

    The problem is that this has what is called a round trip conversion. A pointer converted to int converted back to a pointer. An int is not guaranteed to be able to hold the value of a pointer (an int is signed, a pointer may be be larger than an int) so such a round trip is not guaranteed to give a valid pointer. Any attempt to use that pointer gives undefined behaviour. The common symptom is a program crash. Another common symptom, albeit one that is only detected if you happen to watch for it, is spurious instances of data corruption (aka data poisoning) within your program.

    The type conversion is needed in C++, because C++ does not allow a void pointer to be implicitly converted to another pointer type. The type checking is stronger. Generally, malloc() can be used in C++, but operator new is a better option (because it is compatible with the C++ type system).
    Last edited by grumpy; 03-16-2012 at 06:59 AM.
    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. problem initializing a double array for large array
    By gkkmath in forum C Programming
    Replies: 4
    Last Post: 08-25-2010, 08:26 PM
  2. Initializing pointers always necessary?
    By CodeKate in forum C Programming
    Replies: 24
    Last Post: 08-17-2010, 07:20 PM
  3. trouble initializing a dynamic array of pointers to NULL
    By supernater in forum C++ Programming
    Replies: 8
    Last Post: 09-13-2009, 04:47 PM
  4. Array initializing
    By RoshanX in forum C++ Programming
    Replies: 2
    Last Post: 03-23-2006, 02:40 PM
  5. help on initializing array
    By neversell in forum C Programming
    Replies: 6
    Last Post: 06-30-2002, 05:07 AM