0

I have the following code to create a big 2d array on the heap:

static unsigned char** storagebuffer;
storagebuffer = (unsigned char*) malloc(128 *sizeof(unsigned char *));

for (int i = 0; i < 128; i++)
    storagebuffer[i] = malloc(8192 *sizeof(unsigned char));

This compiles and works OK using GCC but when I do this in a Visual C++ file it gives the following errors:

processing.cpp(11): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>processing.cpp(11): error C2040: 'storagebuffer' : 'int' differs in levels of indirection from 'unsigned char **'
1>processing.cpp(11): error C2440: 'initializing' : cannot convert from 'unsigned char *' to 'int'
1>          There is no context in which this conversion is possible
1>processing.cpp(13): error C2059: syntax error : 'for'
1>processing.cpp(13): error C2143: syntax error : missing ')' before ';'
1>processing.cpp(13): error C2143: syntax error : missing ';' before '<'
1>processing.cpp(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>processing.cpp(13): error C2143: syntax error : missing ';' before '++'
1>processing.cpp(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>processing.cpp(13): error C2086: 'int i' : redefinition
1>          processing.cpp(13) : see declaration of 'i'
1>processing.cpp(13): error C2059: syntax error : ')' 

How can I do this using Visual C++?

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
James
  • 3,957
  • 4
  • 37
  • 82

2 Answers2

1

The problem is that the code is compiled in MS VS as C++ code (see the error message C++ does not support default-int). C++ does not allow implicit conversion from type void * to a pointer of any other type.

storagebuffer[i] = malloc(8192 *sizeof(unsigned char));
                   ^^^^^^ 

You have to cast the pointer explicitly.

Either you should compile the code as C code in MS VS or specify casting operator.

storagebuffer[i] = ( unsigned char * )malloc(8192 *sizeof(unsigned char));

or

storagebuffer[i] = reinterpret_cast<unsigned char *>( malloc(8192 *sizeof(unsigned char)) );

Take into account that this statement

storagebuffer = (unsigned char*) malloc(128 *sizeof(unsigned char *));

have to be written as

storagebuffer = (unsigned char**) malloc(128 *sizeof(unsigned char *));

I think it was simply a typo.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • @Kells1986 My advice is always cast return value of malloc even in C though it allows implicit conversion. – Vlad from Moscow Jul 31 '14 at 09:18
  • `sizeof(unsigned char`) is `1`. And use `new` at least. – edmz Jul 31 '14 at 09:22
  • @black it seems that he compiles the code either as C code or as C++ code depending of the compiler. – Vlad from Moscow Jul 31 '14 at 09:23
  • @black As for this note "sizeof(unsigned char) is 1" then it is always better to specify n * sizeof(unsigned char) instead of using magic numbers n. – Vlad from Moscow Jul 31 '14 at 09:24
  • @VladfromMoscow It is guaranteed by the standard to be `1` byte. It's redundant; not wrong, absolutely. – edmz Jul 31 '14 at 09:27
  • @black I think that I said clear enough how it is better and expressively to write the expression. I am not discussing what is the value of sizeof( unsigned char ). – Vlad from Moscow Jul 31 '14 at 09:29
  • 5
    @VladfromMoscow In C, it's explicitly harmful to cast the return value; if one is writing C code, then one should compile it as C, not C++. If one is writing C++ code, then one should not be `malloc()`ating memory because it's dangerous; standard containers, or smart pointers shall be preferred instead. – The Paramagnetic Croissant Jul 31 '14 at 09:29
  • @Paramagnetic Croissant it is simply a bad style of programming when casting is not used in C. Take the better from C++. The more expressive your code the better. Do not advice others to use bad style of programming. For example can you say what type of an object is there allocated p = malloc( n * sizeof( *p ) );?! – Vlad from Moscow Jul 31 '14 at 09:31
  • 2
    @VladfromMoscow "it is simply a bad style of programming when casting is not used in C" - lol, I laughed out loud reading this. It's **you** who are advising the use of bad style. "can you say what type of an object is there allocated" - I can, because I always coalesce the mallocation inside the initialization: `Foo *p = malloc(sizeof *p);`. [Read this](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) for more information. – The Paramagnetic Croissant Jul 31 '14 at 09:41
  • @The Paramagnetic Croissant It seems you write very simple programs for beginners if you can always use malloc inside the initialization. – Vlad from Moscow Jul 31 '14 at 09:44
  • 2
    @VladfromMoscow I am not willing to discuss this further. You are making unwarranted and incorrect assumptions about what type of code I am writing. Being personal and utilizing an argumentum ad hominem shows that you have no real arguments against the ones brought up in the linked answer. Good day. – The Paramagnetic Croissant Jul 31 '14 at 09:54
0

With VS 2013 I did not get the error you posted here. I got the following error error C2440: '=' : cannot convert from 'unsigned char ' to 'unsigned char *' 1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

The reason for this error is in the malloc statement storagebuffer the typecast is done to (unsigned char*) instead of (unsigned char**). Once that is done it compiled without any errors. Below is the code snippet.

    #include <stdio.h>
    #include <stdlib.h>

    int _tmain(int argc, _TCHAR* argv[])
    {
        static unsigned char** storagebuffer;
        storagebuffer = (unsigned char*)malloc(128 * sizeof(unsigned char *));

        for (int i = 0; i < 128; i++)
            storagebuffer[i] = (unsigned char*)malloc(8192 * sizeof(unsigned char));

        return 0;
    }
Prasanna
  • 23
  • 1
  • 6