invalid conversion from void* to int**

  • Thread starter =?ISO-8859-1?Q?Martin_J=F8rgensen?=
  • Start date
?

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

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
 
R

Rolf Magnus

Martin said:
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.
 
G

Guest

Rolf said:
Martin Jørgensen wrote: -snip-

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

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

That's a ridiculous comment.
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
 
P

Phlip

Martin said:
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.
 
I

Ian Collins

Martin said:
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.
 
R

Rolf Magnus

Martin said:
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.
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++.
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.
 
?

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

Phlip said:
Martin Jorgensen wrote:




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
 
O

Old Wolf

Martin said:
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.
 
?

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

Old said:
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?
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;
}
}
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?
Those are pointers, not arrays.

You're right. I was thinking of what they pointed to instead.
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
 
O

Old Wolf

Martin said:
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).
 
?

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

Old said:
Martin Jørgensen wrote:




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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top