473,785 Members | 2,824 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Question about void pointers

Is this valid?

int a[20];
void *b;

b = (void *)a; // b points to a[0]

b += 5*sizeof(*a); // b points to a[5]

a[5] = 100;

printf( "%d\n" , *((int *)b) ); // prints 100

If so, if a had been a struct, would it still work?

Is there a possibility that the array could contain some padding, so
rather than sizeof, the assignment would be

b += 5*( (void *)(&(a[1])) - (void *)(&(a[0]));

which seems more more complex.

Would any padding be incorporated into sizeof anyway?
Sep 16 '08
160 5714
s0****@gmail.co m wrote:
....
Well, I'm not talking specifically about an array of int, but any
arbitrary object. A realistic case where I would find it convenient to
perform arithmetic on a void * is when you have a void * object and
need to call a function that takes a void *. For example, suppose you
have a buffer that you want to append to another buffer:

void *buf1;
void *buf2;
int n, buf2len;
...
memcpy(buf1 + n, buf2, buf2len);

This would append 'buf2' to 'buf1', assuming 'n' is the starting point
of the appending operation. Without being able to perform arithmetic
on the void *, you would have to call memcpy() like this:

memcpy((char *) buf1 + n, buf2, buf2len);
In the abstract, that looks plausible, but lets get down to details -
why is 'n' measured in bytes? If there's a good reason for it, then that
reason also probably implies that buf1 and buf2 should be pointers to a
character type, not void*. Another possibility is that your code should
have been written so that buf1 already points at the destination of the
memcpy, rather than pointing n bytes earlier. Without a more concrete
example, it's hard to say what the correct design would be, but it's
unlikely to be the one you gave.
Sep 17 '08 #121
s0****@gmail.co m writes:
On Sep 17, 12:36*pm, Keith Thompson <ks***@mib.orgw rote:
[...]
>If you show us a problem you need to solve, involving an array of int,
for which int* pointers are not adequate, please do so, and we can
discuss the best way to go about it.

Well, I'm not talking specifically about an array of int, but any
arbitrary object. A realistic case where I would find it convenient to
perform arithmetic on a void * is when you have a void * object and
need to call a function that takes a void *. For example, suppose you
have a buffer that you want to append to another buffer:

void *buf1;
void *buf2;
int n, buf2len;
...
memcpy(buf1 + n, buf2, buf2len);

This would append 'buf2' to 'buf1', assuming 'n' is the starting point
of the appending operation. Without being able to perform arithmetic
on the void *, you would have to call memcpy() like this:

memcpy((char *) buf1 + n, buf2, buf2len);
Which, if you insist on using void*, is exactly what you have to do if
you're using a compiler other than gcc.

Presumably you know the type of the buffer you're pointing to.
Perhaps it's an array of unsigned char. If it is, just declare the
pointers buf1 and buf2 as unsigned char*.

unsigned char *buf1 = /* whatever */;
unsigned char *buf2 = /* whatever */;
int n = /* whatever */;
int buf2len = /* whatever */;
...
memcpy(buf1 + n, buf2, buf2len);

Note that the arguments ``buf1 + n'' and ``buf2'', which in my snippet
are of type unsigned char*, will be implicitly converted to void*.

If you want to point to an object of a certain type, use a pointer to
that type. If you want to point to an object that you're going to
treat as an array of bytes, use unsigned char*. If you want to point
to an object of some arbitrary type and you *don't* need to treat it
as an array of bytes, use void*.

Do you have a more complete and/or convincing example?

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 17 '08 #122
On Sep 17, 1:36*pm, James Kuyper <ja*********@ve rizon.netwrote:
s0****@gmail.co m wrote:
Well, I'm not talking specifically about an array of int, but any
arbitrary object. A realistic case where I would find it convenient to
perform arithmetic on a void * is when you have a void * object and
need to call a function that takes a void *. For example, suppose you
have a buffer that you want to append to another buffer:
* * void *buf1;
* * void *buf2;
* * int n, buf2len;
* * ...
* * memcpy(buf1 + n, buf2, buf2len);
This would append 'buf2' to 'buf1', assuming 'n' is the starting point
of the appending operation. Without being able to perform arithmetic
on the void *, you would have to call memcpy() like this:
* * memcpy((char *) buf1 + n, buf2, buf2len);

In the abstract, that looks plausible, but lets get down to details -
why is 'n' measured in bytes?
I guess I just find it natural to relate void pointers with bytes, but
in cases where I don't need to examine the representation of the
bytes. Don't you feel that way too?

Sebastian

Sep 17 '08 #123
On Sep 17, 1:45*pm, Keith Thompson <ks***@mib.orgw rote:
s0****@gmail.co m writes:
On Sep 17, 12:36*pm, Keith Thompson <ks***@mib.orgw rote:
[...]
If you show us a problem you need to solve, involving an array of int,
for which int* pointers are not adequate, please do so, and we can
discuss the best way to go about it.
Well, I'm not talking specifically about an array of int, but any
arbitrary object. A realistic case where I would find it convenient to
perform arithmetic on a void * is when you have a void * object and
need to call a function that takes a void *. For example, suppose you
have a buffer that you want to append to another buffer:
* * void *buf1;
* * void *buf2;
* * int n, buf2len;
* * ...
* * memcpy(buf1 + n, buf2, buf2len);
This would append 'buf2' to 'buf1', assuming 'n' is the starting point
of the appending operation. Without being able to perform arithmetic
on the void *, you would have to call memcpy() like this:
* * memcpy((char *) buf1 + n, buf2, buf2len);

Which, if you insist on using void*, is exactly what you have to do if
you're using a compiler other than gcc.

Presumably you know the type of the buffer you're pointing to.
That's an excellent point: what if you _don't_ know what it's really
pointing to? For example, functions such as memcpy(), memmove(),
memset(), etc., are used extensively to deal with objects of any type.
So this functions take void *'s, and they might be pointing to an int,
to a char, to a structure, or anything you can think of. I'm sure the
implementor of such a function would find it enjoyable to be able to
perform void pointer arithmetic!

<snip>

Sebastian

Sep 17 '08 #124
s0****@gmail.co m wrote:
On Sep 17, 1:36 pm, James Kuyper <ja*********@ve rizon.netwrote:
>s0****@gmail.co m wrote:
>>Well, I'm not talking specifically about an array of int, but any
arbitrary object. A realistic case where I would find it convenient to
perform arithmetic on a void * is when you have a void * object and
need to call a function that takes a void *. For example, suppose you
have a buffer that you want to append to another buffer:
void *buf1;
void *buf2;
int n, buf2len;
...
memcpy(buf1 + n, buf2, buf2len);
This would append 'buf2' to 'buf1', assuming 'n' is the starting point
of the appending operation. Without being able to perform arithmetic
on the void *, you would have to call memcpy() like this:
memcpy((char *) buf1 + n, buf2, buf2len);
In the abstract, that looks plausible, but lets get down to details -
why is 'n' measured in bytes?

I guess I just find it natural to relate void pointers with bytes, but
in cases where I don't need to examine the representation of the
bytes. Don't you feel that way too?
No, truly I don't. If I want to point at bytes, I use an
`unsigned char*'.

The time to use `void*' is when you don't know what you're
pointing at, when the function can do its job without knowing
or caring about the type of the data it's manipulating. This
usually means one of two things:

1) The function deals with the bytes that represent an object,
not with the object as such. I/O functions, memcpy(),
free(), and so on are type-blind in this sense: They just
care about the object's bytes, not about its nature.

2) The function is a framework operating on "abstracted data
types." It doesn't know what kind of data it's handling,
but it passes the data pointers along to type-specific
functions that do know. qsort() and bsearch() are examples
of this style.

In both cases `void*' is a convenience rather than a necessity,
and C existed for a long time before the convenience appeared. One
could (did) use character pointers where now one uses `void*', and
everything was fine -- except that the function's callers had to
write all those ugly casts:

struct foobar *foo = (struct foobar*)malloc( 42 * sizeof *foo);
memset ((char*)foo, 'X', 42 * sizeof *foo);
fwrite ((char*)foo, sizeof *foo, 42, stream);
free ((char*)foo);

.... and so on. (Hoping to suppress a reflex: in C-without-void, the
cast in the first line *is* necessary.) The existence of `void*' --
in particular, its ability to convert to and from other data pointer
types without casting -- allows all that uglification to disappear.
True, for functions of type (1) it probably adds a conversion inside
the function -- but since the usual reason for writing a function
once is to be able to call it from N different places, there's a net
decrease in casting.

To summarize: If you know you're dealing with objects of type T,
use a `T*' -- this is the cleanest and safest option, when available.
If you intend to deal with bytes use `unsigned char*'. If you don't
care what you're dealing with, or if you want to deal with bytes but
want to relieve your callers of casting, use `void*'.

--
Er*********@sun .com
Sep 17 '08 #125
s0s...@gmail.co m wrote:
On Sep 17, 1:36�pm, James Kuyper <ja*********@ve rizon.netwrote:
s0****@gmail.co m wrote:
....
In the abstract, that looks plausible, but lets get down to details -
why is 'n' measured in bytes?

I guess I just find it natural to relate void pointers with bytes, but
in cases where I don't need to examine the representation of the
bytes. Don't you feel that way too?
No - i relate void pointers to objects of unknown size, not bytes.
For me, the natural form to use when talking about bytes is unsigned
char*, not void*.
Sep 17 '08 #126
s0s...@gmail.co m wrote:
....
pointing to? For example, functions such as memcpy(), memmove(),
memset(), etc., are used extensively to deal with objects of any type.
So this functions take void *'s, and they might be pointing to an int,
to a char, to a structure, or anything you can think of. I'm sure the
implementor of such a function would find it enjoyable to be able to
perform void pointer arithmetic!
I would expect the implementation to be in assembly language. One of
the key reasons why those functions are standardized is that on most
platforms there's a lot of room for improvement if the routine is hand-
assembled rather than compiled from C source code.

Keep in mind that the standard defines the behavior of these functions
in terms of actions on an array of unsigned char. It seems quite
natural to me that, if an implementor chooses to implement one of
those routines using C code, that the code would convert the
parameters into unsgned char* before making any use of them. That's
precisely what I would recommend that you do on any comparable routine
that takes a void* pointer and a byte count as arguments.
Sep 17 '08 #127
On Sep 17, 2:24*pm, Eric Sosman <Er*********@su n.comwrote:
s0****@gmail.co m wrote:
>On Sep 17, 1:36 pm, James Kuyper <ja*********@ve rizon.netwrote:
>>s0****@gmail.co m wrote:
Well, I'm not talking specifically about an array of int, but any
arbitrary object. A realistic case where I would find it convenient to
perform arithmetic on a void * is when you have a void * object and
need to call a function that takes a void *. For example, suppose you
have a buffer that you want to append to another buffer:
* * void *buf1;
* * void *buf2;
* * int n, buf2len;
* * ...
* * memcpy(buf1 + n, buf2, buf2len);
This would append 'buf2' to 'buf1', assuming 'n' is the starting point
of the appending operation. Without being able to perform arithmetic
on the void *, you would have to call memcpy() like this:
* * memcpy((char *) buf1 + n, buf2, buf2len);
In the abstract, that looks plausible, but lets get down to details -
why is 'n' measured in bytes?
>I guess I just find it natural to relate void pointers with bytes, but
in cases where I don't need to examine the representation of the
bytes. Don't you feel that way too?

* * *No, truly I don't. *If I want to point at bytes, I use an
`unsigned char*'.
(It seems you're referring to the other kinds of bytes; see below.)
* * *The time to use `void*' is when you don't know what you're
pointing at, when the function can do its job without knowing
or caring about the type of the data it's manipulating. *This
usually means one of two things:

* * *1) The function deals with the bytes that represent an object,
* * * * not with the object as such. *I/O functions, memcpy(),
* * * * free(), and so on are type-blind in this sense: They just
* * * * care about the object's bytes, not about its nature.
Exactly, that's the "bytes" I was referring to. The word "bytes" is
also used to refer to characters. But I was referring to the bytes
that constitute an arbitrary object: int, double, struct, etc., and
that if examined, they will appear to have meaningless values. This is
also why I find it more natural to use void *: you aren't going to
examine what it points to, because all you're going to see are some
arbitrary bits that constitute an object of (possibly) bigger size.

Sebastian

Sep 17 '08 #128
s0****@gmail.co m writes:
On Sep 17, 2:24*pm, Eric Sosman <Er*********@su n.comwrote:
[...]
>* * *1) The function deals with the bytes that represent an object,
* * * * not with the object as such. *I/O functions, memcpy(),
* * * * free(), and so on are type-blind in this sense: They just
* * * * care about the object's bytes, not about its nature.

Exactly, that's the "bytes" I was referring to. The word "bytes" is
also used to refer to characters. But I was referring to the bytes
that constitute an arbitrary object: int, double, struct, etc., and
that if examined, they will appear to have meaningless values. This is
also why I find it more natural to use void *: you aren't going to
examine what it points to, because all you're going to see are some
arbitrary bits that constitute an object of (possibly) bigger size.
unsigned char is used for both kinds of "bytes".

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 17 '08 #129
s0****@gmail.co m wrote:
Nick Keighley <ni************ ******@hotmail. comwrote:
.... big snip ...
>
>so now you know- so don't do it again

Why not? I'll simply keep in mind that it works only under a
certain compiler.
Because, if you do it properly, you will never have to rewrite it
again. Laziness pays. Whatever 'it' is.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.
Sep 18 '08 #130

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
2577
by: kazack | last post by:
I am under the the impression that a variable is what is stored in a memory address and a pointer is the memory address of the variable? I was looking to use a function that does not return a value void whatever(whatever) and not have a variable global but in main and change the value in the void whatever function. using namespace std; void whatever(int);
18
2130
by: steve | last post by:
I'm trying to create a structure of three pointers to doubles. For which I have: typedef struct { double *lst_t, *lst_vc, *lst_ic; } last_values; I then need to allocate space for last_values as well as assign the value of a pointer to the assigned space. Which I think I'm doing by using:
14
1347
by: streamkid | last post by:
i'm a learning newbie at c++... and i have the following question... reading some source code, i saw this: int function(const void * one, const void * two) { int var1, var2; var1 = *((int*)one); var2 = *((int*)two); /* sm other code here*/ }
21
1853
by: Bo Yang | last post by:
As long as I write c++ code, I am worry about the pointer. The more the system is, the dangerous the pointer is I think. I must pass pointers erverywhere, and is there a way to ensure that every object pointered by any pointer will be deleted and only be deleted once?
4
1860
by: Jeffrey Spoon | last post by:
Hello, I am trying to make a simple function that returns a pointer to another function. In my header file I've declared my function pointer: void (*pStateFunction) (void); //assume the function pointed to returns void and the actual function that returns the pointer: void* getState(CString myString);
10
1719
by: Zero | last post by:
Hello all, I wonder about void? To which category in the C programming language does it belong? Of how many bits consits void? Is it possible to define a varibale called void a;
21
1564
by: Chad | last post by:
At the following url http://c-faq.com/lib/qsort2.html, they have the following Q: Now I'm trying to sort an array of structures with qsort. My comparison function takes pointers to structures, but the compiler complains that the function is of the wrong type for qsort. How can I cast the function pointer to shut off the warning? A: The conversions must be in the comparison function, which must be declared as accepting ``generic...
17
2328
by: Ben Bacarisse | last post by:
candide <toto@free.frwrites: These two statements are very different. The first one is just wrong and I am pretty sure you did not mean to suggest that. There is no object in C that is the same as its address. The second one simply depends on a term that is not well-defined. Most people consider the type to be an important part of the notion of
18
2646
by: mdh | last post by:
May I ask the following. By K&R's own admission, the example used to describe function pointers is complex ( on P119). In addition, the use of casts has been stated by some on this group as being, again, a poor/bad example of it's use. For the moment, accepting these criticisms, I would still like to get some insight into why/how some things work as even poor code is enlightening, to me at least. The example uses K&R's version of...
28
1825
by: junky_fellow | last post by:
Guys, Consider a function func(void **var) { /* In function I need to typecast the variable var as (int **) I mean to say, I need to access var as (int **) }
0
9645
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10327
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10092
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9950
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8973
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6740
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4053
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2879
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.