-4

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];
           }
      }
    }
 } 
Nilam Naghor
  • 57
  • 3
  • 12

2 Answers2

3

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
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • 1
    Man. I wish I'd seen this go up. Would have gone to bed half an hour ago. Only thing I'd add is a quick note on why `'\n'` and not `endl`, and I'd change the inner most `auto const& x` to `auto const& z` or similar to prevent confusion over the duplicated variable name. – user4581301 Sep 09 '16 at 06:46
  • @user4581301 duh. I totally spaced on the `z`. The '\n' is, in a continual effort, to remind myself that unnecessary direct flushing requests is something that should be avoided. Sutter and Stroustrup talk about it briefly in the [Core C++ Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rio-endl). Thanks the for catching the innermost index. – WhozCraig Sep 09 '16 at 16:47
0

Only for what you ask: You should explicit do the type cast from void* to others in c++ programs.

And you should consider using new and delete instead.

apple apple
  • 10,292
  • 2
  • 16
  • 36