Search code examples
c++structurecalloc

invalid conversion from void* to strcut* in c++


when i try to use calloc for continuous memory allocation it gives me error like.. invalid conversion from void* to slotstruct(*)[100][1500] in c++

here is my code :

typedef struct
 {
   int id;
   bool used;
 }slotstruct;
 int main(){
       slotstruct ( *slot1 )[100][1500];
       slot1 = calloc( 1, 3 * sizeof( *slot1 ) );
      for(i=0;i<3;i++){
         for(j=0;j<100;j++){
            for(k=0;k<1500;k++){
                  cout << "Addresses are : "<<slot1[i][j][k];
           }
      }
    }
 } 

Solution

  • The C language allows implicit conversion (without casts) of void* to any other object pointer type. Such is not the case in C++. Your options are:

    • Don't compile C code with a C++ compiler (easiest).
    • Perform the proper cast to avoid the error (ill advised, casts, especially for beginners, are often used to hide problems rather than solve them. Abuse of them for that very purpose is, unfortunately, not uncommon. It would, however, "solve" your issue here).
    • Use new[] and delete[] for your sequence allocation. No casting is required, and if your data type ever becomes non-trivial, it will still work.
    • Don't use manual memory allocation at all, and instead opt for an RAII approach.

    The first of these is obvious, the rest are shown below


    Using a cast

    Will work in this case with no ill effects because your slotstruct type is trivial:

    slot1 = (slotstruct (*)[100][1500])calloc( 1, 3 * sizeof( *slot1 ) ); // allocates
    free(slot1); // destroys
    

    Using new[] (and delete[])

    No cast required:

    slot1 = new slotstruct[3][100][1500]; // allocates..
    delete [] slot1; //.. destroys
    

    C++ Alternative using RAII

    A more proper C++ RAII approach for what you appear to be trying to accomplish looks like this:

    #include <iostream>
    #include <array>
    #include <vector>
    
    struct slotstruct
    {
        int id;
        bool used;
    };
    
    int main()
    {
        std::vector<std::array<std::array<slotstruct,1500>, 100>> slots(3);
    
        for (auto const& x : slots)
            for (auto const& y : x)
                for (auto const& z : y)
                    std::cout <<"Address is : " << static_cast<const void*>(&z) << '\n';
    }
    

    Output (varies)

    Address is : 0x100200000
    Address is : 0x100200008
    Address is : 0x100200010
    Address is : 0x100200018
    Address is : 0x100200020
    ...
    Address is : 0x10056ee60
    Address is : 0x10056ee68
    Address is : 0x10056ee70
    Address is : 0x10056ee78