CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Join Date
    Feb 2009
    Posts
    326

    void* and sizeof()

    Hi,

    Using void* and sizeof is it possible to get the value of the object ?

    I understand that dereferencing a void pointer is not directly possible. Is there a way (like casting) or something else to get the value of the object.

    The problem is I wouldn't know the type of the object to cast to, I would only know the size of the object and a void pointer to the object.

    something similar to what qsort does in stdlib.h, using merely the void pointer and sizeof, I think it manages to access the object, otherwise wouldn't be able to sort it.

    Below shown is an example in which inside the function f1, I am suppose to access the object.

    Code:
    class ClassA
    {};
    
    //Inside f1, I have to access the value of the object that pPtr1 points to
    void f1(void* pPtr1, const int pSizeOfObj)
    {}
    
    int main()
    {
    
        ClassA objA;
        
        f1(&objA, sizeof(objA));
        
    
        return(0);
    }
    Thanks,
    Muthu

  2. #2
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    Re: void* and sizeof()

    No, it isn´t. When you cast to void* you strip all information from that pointer it originally was.

    PS:
    qsort requires a custom comparison function that accepts two void* parameters, it´s up to the caller to implement the comparison function properly and cast the pointers to the appropriate type.
    Last edited by GNiewerth; September 18th, 2009 at 03:56 AM.
    - Guido

  3. #3
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    Re: void* and sizeof()

    Quote Originally Posted by Muthuveerappan View Post
    something similar to what qsort does in stdlib.h, using merely the void pointer and sizeof, I think it manages to access the object, otherwise wouldn't be able to sort it.
    fyi : qsort also requires a function to compare the elements. In the function, you
    cast the void * pointers to the appropriate type.

  4. #4
    Join Date
    Feb 2009
    Posts
    326

    Re: void* and sizeof()

    Thanks both of you for explaining it to me, I guess I missed the following points:

    1) The fact that compare function pointer in qsort was the one that was actually accessing the value. And inside the function pointer they were actually doing the casting to required type, as they knew the type. And function pointer was passed an argument

    2) And void* and sizeof() is merely to traverse through the elements in the array

    I will try this and then get back if I have any doubts.
    Last edited by Muthuveerappan; September 18th, 2009 at 10:58 AM.

  5. #5
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: void* and sizeof()

    Why do you want to know the size of your object? Even if you do know the type, unless your only have POD members, sizeof won't give you the right number anyway.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: void* and sizeof()

    The first thing I would ask is why not use a template function based on type instead of the void* and sizeof() shenanigans.
    Code:
    template <typename T>
    void f1(T* pPtr1)
    {}
    Now you don't need to compute sizeof() when traversing fields, since T* is the pointer to the actual type.

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Feb 2009
    Posts
    326

    Re: void* and sizeof()

    GCDEF
    ---------
    1) I thought I could traverse through an array of elements starting from the address of the array if I know the sizeof(). Correct me if I am wrong..... I just tried it and I realized void* can't be used in pointer arithmetic. So is there a way to to make the void* point to the different elements of the array without actually the knowing the type of the array and merely knowing the sizeof() of the type ?

    2) What is a POD member ?

    Paul - I could use a template, I just wanted to try it using void* and function pointers, never done it before

    Question
    -----------
    1) How do I traverse through the array of a certain type when all I have is a void* to the start of the array and a sizeof() of the type ?

  8. #8
    Join Date
    Oct 2005
    Location
    England
    Posts
    803

    Re: void* and sizeof()

    Quote Originally Posted by Muthuveerappan View Post
    GCDEF

    2) What is a POD member ?
    POD (Plain Old Datatype) - The fundamental data types such as bool, int and double. So an Object which contains only these types as members.

    Code:
    struct POD
    {
        bool b;
        int i;
    };
    
    
    struct NONPOD
    {
        string s;
        int i;
    };
    Rich

    Visual Studio 2010 Professional | Windows 7 (x64)
    Ubuntu

  9. #9
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: void* and sizeof()

    Quote Originally Posted by Muthuveerappan View Post
    GCDEF
    ---------
    1) I thought I could traverse through an array of elements starting from the address of the array if I know the sizeof(). Correct me if I am wrong..... I just tried it and I realized void* can't be used in pointer arithmetic. So is there a way to to make the void* point to the different elements of the array without actually the knowing the type of the array and merely knowing the sizeof() of the type ?

    2) What is a POD member ?

    Paul - I could use a template, I just wanted to try it using void* and function pointers, never done it before

    Question
    -----------
    1) How do I traverse through the array of a certain type when all I have is a void* to the start of the array and a sizeof() of the type ?
    If you want to use pointer arithmetic, your array would consist of pointers, so you'd want sizeof the pointer, not sizeof the object, and the size of pointers is consistent, so you don't need sizeof at all. If it's an array, what's wrong with just accessing the elements directly by index?

  10. #10
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: void* and sizeof()

    Quote Originally Posted by Muthuveerappan View Post
    GCDEF
    ---------
    1) I thought I could traverse through an array of elements starting from the address of the array if I know the sizeof(). Correct me if I am wrong..... I just tried it and I realized void* can't be used in pointer arithmetic. So is there a way to to make the void* point to the different elements of the array without actually the knowing the type of the array and merely knowing the sizeof() of the type ?
    You can cast to char*. Since a char is 1 byte, that will allow you to move around the array in byte counts.

    However, that isn't a recommended practice.

  11. #11
    Join Date
    Feb 2009
    Posts
    326

    Re: void* and sizeof()

    Quote Originally Posted by GCDEF View Post
    If you want to use pointer arithmetic, your array would consist of pointers, so you'd want sizeof the pointer, not sizeof the object, and the size of pointers is consistent, so you don't need sizeof at all. If it's an array, what's wrong with just accessing the elements directly by index?
    take for example qsort that is defined in stdlib.h

    Code:
    void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
    it only accepts a void* that points to the start of the array of elements, and somehow manages to traverse through the array. It knows the size of the array and the size of each element.
    The comparison of value is done by the function pointer.

    I was wondering how it was possible to traverse through the elements of the array, and wanted to a simple (very basic example) to traverse through the array using a void* when the destination type is unknown as in qsort.

    I am not using a array of void pointers, so wouldn't need to know the size of the void pointer, I am using a array and a void pointer points to that array.

    Note - I am just trying to make the void pointer point to the next element.

    Any suggestions ? pls correct me if I am missing something.

    Quote Originally Posted by Lindley View Post
    You can cast to char*. Since a char is 1 byte, that will allow you to move around the array in byte counts.

    However, that isn't a recommended practice.
    Thanks a lot Lindley, I agree it might not be a recommended practice, but it is the only way so far I know (after your suggestion) to access the various elements of the array.

    Given below is the implementation of the same:
    Code:
    #include <iostream>
    using std :: cout;
    using std :: endl;
    
    class ClassA
    {
        double d1;
        double d2;
        int    i1;
        int    i2;
        char   c1;
        char   c2;
        
    };
    
    void printAddress(const ClassA pObjA[], const int pNumberOfElements);
    void printAddressUsingVoidPtr(const void* pVoidPtr, const int pNumberOfElements, const int pSizeOfElement);
    
    
    int main()
    {
        const int SIZE_OF_ARRAY = 5;
        ClassA objA[SIZE_OF_ARRAY];
    
        system("clear");
        
        printAddress(objA, SIZE_OF_ARRAY);
        
        void *voidPtr = objA;
        printAddressUsingVoidPtr(objA, SIZE_OF_ARRAY, sizeof(ClassA));
        
        return(0);
    }
    
    void printAddress(const ClassA pObjA[], const int pNumberOfElements)
    {
        cout << "Actual Address:\n";
        for(int index = 0; index < pNumberOfElements; index ++)
            cout << "&pObjA[" << index << "] = " << &pObjA[index] << endl;
    
        cout << endl;
    }
    
    void printAddressUsingVoidPtr(const void* pVoidPtr, const int pNumberOfElements, const int pSizeOfElement)
    {
        cout << "Address using void pointers\n"
             << "pSizeOfElement = " << pSizeOfElement << endl;
        
    
        for(int index = 0; index < pNumberOfElements; index ++)
        {
            //Doing this to convert to a char pointer to perform pointer arithmetic
            void* voidPtrNonConst = const_cast<void*>(pVoidPtr);
            char* charPtr = static_cast<char*>(voidPtrNonConst) + ( index * pSizeOfElement);
            
            //Converting back to void pointer so that I can print the address using cout
            void* voidPtrToPrint = charPtr;
            
            cout << voidPtrToPrint << endl;
        }
    
        cout << endl;
    }
    Output:
    Code:
    Actual Address:
    &pObjA[0] = 0x7fff5fbfc760
    &pObjA[1] = 0x7fff5fbfc780
    &pObjA[2] = 0x7fff5fbfc7a0
    &pObjA[3] = 0x7fff5fbfc7c0
    &pObjA[4] = 0x7fff5fbfc7e0
    
    Address using void pointers
    pSizeOfElement = 32
    0x7fff5fbfc760
    0x7fff5fbfc780
    0x7fff5fbfc7a0
    0x7fff5fbfc7c0
    0x7fff5fbfc7e0
    Last edited by Muthuveerappan; September 19th, 2009 at 12:18 AM. Reason: Added the output of the program

  12. #12
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: void* and sizeof()

    Quote Originally Posted by Muthuveerappan View Post
    take for example qsort that is defined in stdlib.h

    Code:
    void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
    it only accepts a void* that points to the start of the array of elements, and somehow manages to traverse through the array. It knows the size of the array and the size of each element.
    Two of the arguments to qsort are the size of the array and the size of its elements. You're telling it that stuff, so it doesn't need sizeof or any other machinations to figure it out. All you'd need to do is increment the starting pointer by size each to get to the next element.

  13. #13
    Join Date
    Feb 2009
    Posts
    326

    Re: void* and sizeof()

    Quote Originally Posted by GCDEF View Post
    Two of the arguments to qsort are the size of the array and the size of its elements. You're telling it that stuff, so it doesn't need sizeof or any other machinations to figure it out. All you'd need to do is increment the starting pointer by size each to get to the next element.
    Below are my views (correct me if I am wrong):

    Size of each element is passed to qsort as an argument. Therefore while invoking the function qsort you would have to pass the size of each element by using the sizeof() function.

    Also I believe sizeof() works for non-POD members such as classes etc.

  14. #14
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: void* and sizeof()

    sizeof() does indeed work for non-POD classes. However, you wouldn't want to use qsort() on a non-POD class.

  15. #15
    Join Date
    Feb 2009
    Posts
    326

    Re: void* and sizeof()

    You could qsort for any type, as long as you are able to define a compare function for that and pass it as a function pointer.

    below shown is an example:

    Code:
    #include <iostream>
    #include <stdlib.h>
    using std :: cout;
    using std :: endl;
    
    class ClassA
    {
        public:
            ClassA() :n1(0) {}
            ClassA(const int pInt) : n1(pInt) {}
            int getN1() const { return(n1); }
    
        private:
            int n1;
    };
    
    
    int compare(const void* pVoidPtr1, const void* pVoidPtr2);
    void display(const ClassA pArray[], const int pNumberOfElements);
    
    
    int main()
    {
        system("clear");
    
        ClassA objA[] = {ClassA(20), ClassA(30), ClassA(18)};
        
        qsort(objA, 3, sizeof(ClassA), compare);
        display(objA, 3);
    
        return(0);
    }
    
    int compare(const void* pVoidPtr1, const void* pVoidPtr2)
    {
        const ClassA *intPtr1 = static_cast<const ClassA*>(pVoidPtr1);
        const ClassA *intPtr2 = static_cast<const ClassA*>(pVoidPtr2);
    
        return(intPtr1 -> getN1() - intPtr2 -> getN1());
    }
    
    void display(const ClassA pArray[], const int pNumberOfElements)
    {
        for(int index = 0; index < pNumberOfElements; index ++)
            cout << pArray[index].getN1() << "  ";
    
        cout << endl;
    }
    Output:
    Code:
    18  20  30

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured