invalid conversion from void* to int**

Discussion in 'C++' started by =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 14, 2006.

  1. Hi,

    I'm using this alloc_mem-function:

    - - - - - - - - - - - - - - - - - - - - - - - -

    void *alloc_mem (size_t num_elems, size_t elem_size,
    char *filename, int line,
    size_t *total_mem)
    {
    void *mem;
    size_t size = num_elems*elem_size;
    size += (sizeof (size_t) <= elem_size) ? elem_size
    : sizeof (size_t);
    mem = malloc(size);

    if (!mem)
    {
    fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n",
    filename, line, (unsigned long) size);
    exit(EXIT_FAILURE);
    }

    /* save memory allocated for this pointer */
    memcpy(((char *)mem)+num_elems*elem_size,
    &size, sizeof size);
    *total_mem += size; /* update total memory allocated untill now */

    return mem;

    }
    - - - - - - - - - - - - - - - - - - - - - - - -

    But I then declared some arrays like:

    double **two_D_double;
    int **two_D_int;
    double *one_D_double;
    int *one_D_int;
    etc. etc...

    MS visual studio 2005 + gcc doesn't complain. But with g++ I get such an
    error as:

    "invalid conversion from void* to int**" (the same for double **)

    I was told I should ask about the g++ compiler here, although the code
    is actually implemented in a C-program. So what's the language
    difference - why can't I do an "implicit conversion from void* to int**"
    in C++ ?


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 14, 2006
    #1
    1. Advertising

  2. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Rolf Magnus Guest

    Martin Jørgensen wrote:

    > Hi,
    >
    > I'm using this alloc_mem-function:
    >
    > - - - - - - - - - - - - - - - - - - - - - - - -
    >
    > void *alloc_mem (size_t num_elems, size_t elem_size,
    > char *filename, int line,
    > size_t *total_mem)
    > {
    > void *mem;
    > size_t size = num_elems*elem_size;
    > size += (sizeof (size_t) <= elem_size) ? elem_size
    > : sizeof (size_t);
    > mem = malloc(size);
    >
    > if (!mem)
    > {
    > fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n",
    > filename, line, (unsigned long) size);
    > exit(EXIT_FAILURE);
    > }
    >
    > /* save memory allocated for this pointer */
    > memcpy(((char *)mem)+num_elems*elem_size,
    > &size, sizeof size);
    > *total_mem += size; /* update total memory allocated untill now */
    >
    > return mem;
    >
    > }
    > - - - - - - - - - - - - - - - - - - - - - - - -
    >
    > But I then declared some arrays like:
    >
    > double **two_D_double;
    > int **two_D_int;
    > double *one_D_double;
    > int *one_D_int;
    > etc. etc...
    >
    > MS visual studio 2005 + gcc doesn't complain. But with g++ I get such an
    > error as:
    >
    > "invalid conversion from void* to int**" (the same for double **)
    >
    > I was told I should ask about the g++ compiler here, although the code
    > is actually implemented in a C-program.


    Don't use g++ for C programs. g++ is the C++ compiler.

    > So what's the language difference -


    You didn't really think C and C++ were exactly the same, did you?

    > why can't I do an "implicit conversion
    > from void* to int**" in C++ ?


    Because that's how the language is defined. Conversions from void* to any
    other object pointer always need a cast.
     
    Rolf Magnus, May 14, 2006
    #2
    1. Advertising

  3. Rolf Magnus wrote:
    > Martin Jørgensen wrote:

    -snip-

    > Don't use g++ for C programs. g++ is the C++ compiler.


    That wasn't the question.

    >>So what's the language difference -

    >
    >
    > You didn't really think C and C++ were exactly the same, did you?


    That's a ridiculous comment.

    >>why can't I do an "implicit conversion
    >>from void* to int**" in C++ ?

    >
    >
    > Because that's how the language is defined. Conversions from void* to any
    > other object pointer always need a cast.


    So void* isn't any generic pointer type in C++.


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?UTF-8?B?TWFydGluIErDuHJnZW5zZW4=?=, May 15, 2006
    #3
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Phlip Guest

    Martin Jorgensen wrote:

    > So void* isn't any generic pointer type in C++.


    The best way to think of void* is "a thing that can safely store any
    pointer's value". It's not really a pointer because it doesn't point to a
    type, so you can't dereference it.

    --
    Phlip
    http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
     
    Phlip, May 15, 2006
    #4
  5. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Ian Collins Guest

    Martin Jørgensen wrote:
    >
    > So void* isn't any generic pointer type in C++.
    >

    It is, but not in the same way is in C. C++ doesn't support the
    implicit conversion from void* to other pointer types.

    --
    Ian Collins.
     
    Ian Collins, May 15, 2006
    #5
  6. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Rolf Magnus Guest

    Martin Jørgensen wrote:

    > Rolf Magnus wrote:
    >> Martin Jørgensen wrote:

    > -snip-
    >
    >> Don't use g++ for C programs. g++ is the C++ compiler.

    >
    > That wasn't the question.


    My advice was just an extra give-away for free. Since you wrote that the
    code is C, you shouldn't use a C++ compiler to compile it.

    >>>So what's the language difference -

    >>
    >>
    >> You didn't really think C and C++ were exactly the same, did you?

    >
    > That's a ridiculous comment.


    From what you wrote, it looked to me as if you thought there shouldn't be
    any differences between C and C++.

    >>>why can't I do an "implicit conversion
    >>>from void* to int**" in C++ ?

    >>
    >>
    >> Because that's how the language is defined. Conversions from void* to any
    >> other object pointer always need a cast.

    >
    > So void* isn't any generic pointer type in C++.


    Wrong. It is, though it's needed far less than in C. For type safety, you
    must explicitly tell the compiler, which type you want it to be converted
    to. I fail to see how that could mean it's not a generic pointer type
    anymore.
     
    Rolf Magnus, May 15, 2006
    #6
  7. Phlip wrote:
    > Martin Jorgensen wrote:
    >
    >
    >>So void* isn't any generic pointer type in C++.

    >
    >
    > The best way to think of void* is "a thing that can safely store any
    > pointer's value". It's not really a pointer because it doesn't point to a
    > type, so you can't dereference it.


    But it points to something, so it's a pointer... But I know that about
    the dereferencing stuff. Ok, so there isn't really much else to say
    about that I guess...


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 15, 2006
    #7
  8. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Phlip Guest

    Martin Jørgensen wrote:

    > But it points to something, so it's a pointer...


    Yes, and The Standard calls it a pointer, etc. Just don't think of it as
    one. ;-)

    --
    Phlip
    http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
     
    Phlip, May 15, 2006
    #8
  9. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Old Wolf Guest

    Martin Jørgensen wrote:
    >
    > void *alloc_mem (size_t num_elems, size_t elem_size,
    > char *filename, int line,
    > size_t *total_mem)
    > {
    > void *mem;
    > size_t size = num_elems*elem_size;
    > size += (sizeof (size_t) <= elem_size) ? elem_size
    > : sizeof (size_t);


    Why not just use sizeof(size_t) ?

    > mem = malloc(size);
    >
    > if (!mem)
    > {
    > fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n",
    > filename, line, (unsigned long) size);
    > exit(EXIT_FAILURE);
    > }
    >
    > /* save memory allocated for this pointer */
    > memcpy(((char *)mem)+num_elems*elem_size,
    > &size, sizeof size);


    What is the purpose of storing that size there?
    How are you planning to access it in future?

    > *total_mem += size; /* update total memory allocated untill now */


    You should check here , and in the mutliplication above,
    that you don't overflow a size_t .

    >
    > return mem;
    >
    > }
    > - - - - - - - - - - - - - - - - - - - - - - - -
    >
    > But I then declared some arrays like:
    >
    > double **two_D_double;
    > int **two_D_int;
    > double *one_D_double;
    > int *one_D_int;


    Those are pointers, not arrays.

    > etc. etc...
    >
    > MS visual studio 2005 + gcc doesn't complain. But with g++ I get such an
    > error as:
    >
    > "invalid conversion from void* to int**" (the same for double **)


    You didn't post any code that would give that error.
     
    Old Wolf, May 16, 2006
    #9
  10. Old Wolf wrote:
    > Martin Jørgensen wrote:
    >
    >>void *alloc_mem (size_t num_elems, size_t elem_size,
    >> char *filename, int line,
    >> size_t *total_mem)
    >>{
    >> void *mem;
    >> size_t size = num_elems*elem_size;
    >> size += (sizeof (size_t) <= elem_size) ? elem_size
    >> : sizeof (size_t);

    >
    >
    > Why not just use sizeof(size_t) ?


    Actually I just implemented it after reading the suggestion from
    somebody else. But the point is to store the allocated memory in the end
    of each block. I think it has some technical explanation, something to
    do with "off-numbered" memory address of whatever... I think somebody
    else can explain it - nobody complained about it in comp.lang.c so I
    think it's okay.

    If we think about it, the least extra memory occupation must be sizeof
    (size_t). If elem_size is larger than that, we reserve memory for
    elem_size and I think it's got to do with hitting some memory boundary
    address - anyone?

    >> mem = malloc(size);
    >>
    >> if (!mem)
    >> {
    >> fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n",
    >> filename, line, (unsigned long) size);
    >> exit(EXIT_FAILURE);
    >> }
    >>
    >> /* save memory allocated for this pointer */
    >> memcpy(((char *)mem)+num_elems*elem_size,
    >> &size, sizeof size);

    >
    >
    > What is the purpose of storing that size there?
    > How are you planning to access it in future?


    size_t retrieve_memsize (void *mem, size_t num_elems,
    size_t elem_size)
    {
    size_t size = 0;
    if (mem) {
    memcpy(&size, ((char *)mem)+num_elems*elem_size,
    sizeof size);
    }
    return size;
    }

    void free_mem (void *mem, size_t num_elems,
    size_t elem_size, size_t *total_mem)
    {
    if (mem) {
    size_t size = retrieve_memsize(mem, num_elems, elem_size);
    free(mem);
    *total_mem -= size;
    }
    }

    >> *total_mem += size; /* update total memory allocated untill now */

    >
    >
    > You should check here , and in the mutliplication above,
    > that you don't overflow a size_t .


    What do you mean? How should it overflow?

    >> return mem;
    >>
    >>}
    >>- - - - - - - - - - - - - - - - - - - - - - - -
    >>
    >>But I then declared some arrays like:
    >>
    >>double **two_D_double;
    >>int **two_D_int;
    >>double *one_D_double;
    >>int *one_D_int;

    >
    >
    > Those are pointers, not arrays.


    You're right. I was thinking of what they pointed to instead.

    >>etc. etc...
    >>
    >>MS visual studio 2005 + gcc doesn't complain. But with g++ I get such an
    >>error as:
    >>
    >>"invalid conversion from void* to int**" (the same for double **)

    >
    >
    > You didn't post any code that would give that error.


    It sounds like that, from the other replies in this thread...


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 16, 2006
    #10
  11. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Old Wolf Guest

    Martin Jørgensen wrote:

    >
    >>> *total_mem += size; /* update total memory allocated untill now */

    >>
    >> You should check here , and in the mutliplication above,
    > > that you don't overflow a size_t .

    >
    > What do you mean? How should it overflow?


    Well, if *total_mem is currently 0xFFFFFF00, and you try to add a
    size of 0x200 to it, then *total_mem will now be 0x00000100 .

    Also, the allocation function performs a multiplication. If someone
    requests 0x80000002 * 2 bytes, then your function will happily
    return them an allocation of 4 bytes.

    (All this assumes we're using a 32-bit size_t).
     
    Old Wolf, May 16, 2006
    #11
  12. Old Wolf wrote:
    > Martin Jørgensen wrote:
    >
    >
    >>>> *total_mem += size; /* update total memory allocated untill now */
    >>>
    >>>You should check here , and in the mutliplication above,
    >>>that you don't overflow a size_t .

    >>
    >>What do you mean? How should it overflow?

    >
    >
    > Well, if *total_mem is currently 0xFFFFFF00, and you try to add a
    > size of 0x200 to it, then *total_mem will now be 0x00000100 .
    >
    > Also, the allocation function performs a multiplication. If someone
    > requests 0x80000002 * 2 bytes, then your function will happily
    > return them an allocation of 4 bytes.
    >
    > (All this assumes we're using a 32-bit size_t).


    I don't understand the point. I've used up to about 1,4 GB of memory
    with this code. The machine had 2 GB of RAM total. I don't need anymore
    at this moment.

    However, I would like to see how else this size_t should/could be
    defined because it's probably only a matter of time before computers are
    shipped with 4 GB of memory instead of 1-2 GB.


    Best regards / Med venlig hilsen
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
     
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 17, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ollej Reemt
    Replies:
    7
    Views:
    547
    Jack Klein
    Apr 22, 2005
  2. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    793
    The Real OS/2 Guy
    Oct 28, 2003
  3. Replies:
    5
    Views:
    842
    S.Tobias
    Jul 22, 2005
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    invalid conversion from void* to int**

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 14, 2006, in forum: C Programming
    Replies:
    5
    Views:
    2,480
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=
    May 16, 2006
  5. philwozza
    Replies:
    3
    Views:
    3,537
    philwozza
    May 13, 2006
Loading...

Share This Page