October 5, 2010

void pointers

from comp.lang.c (click)
======

1st paste:

steve wrote:
> Hey guys,
> I have a delemna which I can't figure out.
> This is regarding "void pointers" and I confess, I really don't
> understand them nearly enough to even understand what the problem is.

A void pointer is an address of a region of memory (which may or may not
be occupied).  It is an error to attempt to use a void value in an
expression, hence why compilers will often warn you if you dereference a
void pointer.
(Note to the regulars: I'm probably not being perfectly accurate here,
but I don't think c.l.c pedantry is what steve needs)
(Note to steve: the correct spelling is dilemma)

>   void * params[5];

This creates an array of 5 pointers to void.  It does not create an
array of "void" (as you seem to think).
>   int int_param_values[5] = {1,2,3,4,5};

>   char **str_param_values;

>   str_param_values = malloc(5 * sizeof(char *));
>   str_param_values[0] = malloc(10 * sizeof(char));
>   strcpy(str_param_values[0], "hello");

>   double dbl_param_values[5] = {1.1, 2.2, 3.3};

This creates an array of int, an array of char *, and an array of
double, and initialises them in various ways.
Note two things: firstly, it would probably make more sense for
str_param_values to be an array of 5 char *, and allocated on the stack,
with
        char *str_param_values[5];
There is no obvious need for it to be on the heap.
Secondly, you have not tested the return value of malloc() in either of
these calls; I realise this is only example code (incidentally, you will
get more informative answers if you post actual code; then we know what
you're trying to achieve!) but nonetheless it bears pointing out.

> I can then assign my data values, to the array,
> like so:
>   params[indx] = (void*)int_param_values[ndx];

This is casting an int to a void *.  This is generally incorrect as an
int is not a pointer type.  It just so happens that you are, IIRC,
allowed to do this by a special provision to allow the use of integer
expressions as pointers.  In this case this is clearly not what you are
doing as, for instance, params[0] is now (void *)1; this is now a
pointer to the memory with address 1, which probably isn't even mapped
in your program's address space (if you're on a memory managed
architecture.  On, say, an embedded system you might want to do this).

>   params[indx] = (void*)str_param_values[ndx];

This is casting a char * to a void *.  This is allowed because both are
pointer types.  params[indx] now points to the first character of
str_param_values[ndx].

> These two methods compile just fine and work as expected.
> However, this statement will not compile:
>   params[indx] = (void*)dbl_param_values[ndx];

This is casting a double to a void *.  This is not allowed; a double is
not the same size as, nor anything like, a void *.  Unlike an int it
cannot even reasonably be interpreted as an address; what location in
memory would (void *)0.5 point to?  It's just silly really!

> and generates this compiler error:

> "...cast from 'double' to 'pointer to void' is illegal"

Quite right too.

> When it's all said and done, the idea is to pass the data referred to
> in the array as function parameters,
> like so:

>   MyFunction(params[0], params[1], etc.);

There are two appropriate methods I can think of.  One is to use
varargs; if the function's first argument gives it some way of deducing
the types of the remaining arguments, it can do so.  This is for
instance how the *printf() family of functions work.

The other is to use void *, but populate it not with the data themselves
but with pointers to them; for instance your doubles would become
something like:
        params[indx] = (void *)&dbl_param_values[ndx];
where we assign the /address/ of the double to the pointer; we are now
casting a double * to a void *, which makes much more sense as both are
pointer types.

One question I do have: given your function prototype as you have it,
where the only arguments are the params[] elements, how does the
function know to what the pointers refer (i.e., whether you have used an
int, a double, a char *, or whatever).
If, of course, it is simply, say, printing their addresses, it need not
know; but if it is using their values, it will have to be told, since
not only does it not know their true types, it doesn't even know their
sizes, and a pointer without size information is not much use.

Note also that you cannot make an array of void and store the values
(ints, doubles etc.) in that, because void has no storage size.

Perhaps the real solution to your problems, however, is to use a struct
or union.

I can't really give any more specific advice without some information as
to what you're trying to achieve.

-Edward
==========

2nd paste:

Hey Ed,
thanks for your indepth reply.
Very helpful.

> (Note to steve: the correct spelling is dilemma)

Sorry for that.
I'm one of those people prone to typos and misspelling.
I should have run spell check, I usually do.


> >   void * params[5];

> This creates an array of 5 pointers to void.  It does not create an
> array of "void" (as you seem to think).>   int int_param_values[5] = {1,2,3,4,5};


No, I get that.
My understanding was that it was creating an "array of 5 pointers to
void".
Which I then intended to populate with the addresses of the variables.


> Note two things: firstly, it would probably make more sense for
> str_param_values to be an array of 5 char *, and allocated on the stack,
> with
>         char *str_param_values[5];


Actually, I did try that.
It did not produce the result I was hoping for.



> This is casting a double to a void *.  This is not allowed; a double is
> not the same size as, nor anything like, a void *.  Unlike an int it
> cannot even reasonably be interpreted as an address; what location in
> memory would (void *)0.5 point to?  It's just silly really!

Clearly I'm wrong here, but, I was making the 'assumption' that a
"pointer to void" was just that,
a pointer to the address of a variable of an undertermined type.
Regardless of the size of the variable.
On a given system, are not addresses the same size ?

What I'm after here, is a "generic" mechanism for holding addresses of
mixed variable types.
i.e.: an array of addresses.
Be they of type int, or char, or double, etc.

What I'm (really) after here is to construct a 'generic mechanism' for
calling functions within DLLs at RunTime.
These DLLs, their Functions and Parameters passed are not known at
compile time.

Research indicated that void pointers was the way to do this.

Suggestions ?

Steve 

==========

3rd paste:

steve wrote:
>> Note two things: firstly, it would probably make more sense for
>> str_param_values to be an array of 5 char *, and allocated on the stack,
>> with
>>         char *str_param_values[5];
>

> Actually, I did try that.
> It did not produce the result I was hoping for.

Curious.  It certainly should have.

>> This is casting a double to a void *.  This is not allowed; a double is
>> not the same size as, nor anything like, a void *.  Unlike an int it
>> cannot even reasonably be interpreted as an address; what location in
>> memory would (void *)0.5 point to?  It's just silly really!

> Clearly I'm wrong here, but, I was making the 'assumption' that a
> "pointer to void" was just that,
> a pointer to the address of a variable of an undertermined type.
> Regardless of the size of the variable.
> On a given system, are not addresses the same size ?

Your assumption is valid; the problem is that you weren't putting a
pointer to the double into the void *, you were trying to put the double
itself into the void *.  As mentioned elsewhere in the thread, the '&'
operator is what you're looking for.

> What I'm after here, is a "generic" mechanism for holding addresses of
> mixed variable types.
> i.e.: an array of addresses.
> Be they of type int, or char, or double, etc.

> What I'm (really) after here is to construct a 'generic mechanism' for
> calling functions within DLLs at RunTime.
> These DLLs, their Functions and Parameters passed are not known at
> compile time.

> Research indicated that void pointers was the way to do this.

Firstly, I can't think of a good reason why you would want to do this.
It sounds as though you've come up with some idea for a 'generic
mechanism' without actually having any use cases in mind.
Besides, linking against ill-defined interfaces is a bad idea.  If
you're trying to define functionality at runtime, an embedded scripting
language is the way to go.
But if you /really/ want this, void pointers will do it - but you have
to remember that what you assign to the void pointer has to, itself, be
a pointer too (hence why your double to void * cast wasn't valid).  Also
remember that if you pass a pointer, the callee can modify the
referenced object.  This may not be what you want.
What it /really/ sounds like is that you want function overloading
and/or dynamic types - in other words, you're trying to make C more like
C++ or Java.  From my perspective that seems like a silly thing to do:
why would you want C++ in the first place - and if you do, you know
where to find it ;)


-Edward
==========

 BTW, the website of Edward is worth viewing.

October 3, 2010

visualize resume

两篇讲美化简历的日志,从第一篇阮一峰的日志可以链接到第二篇(click)。乍一看心里还在想,若要使能这么做简历简直太炫了。直到看到英文那篇日志最后的评论,才算是豁然开朗。转贴到这里。


All of them suck. It’s nice eyecandy, but as a recruiter I wouldn’t want to waste my time to read them. My eyes would be hopping around without focus and I would be confused where to read next.

Evalotta Lamm's one would be the best of them if she had used only one column and a classic list from top to bottom. All the others that use two or more columns or completely defy any resumé standard are crap.

Imagine what Albert Lo's, Luc Pestille's and Sarah Parmenter's example looks like if the recruiter has to copy/print the resumé in black and white…

Also never ever make your name stand out in a huge text size, come down from your high horse. No boss cares about someone that proudly displays his name, but has little experience or bad works. Even with a succesful career, you don’t need to show your name in an egoistical, arrogant way.

Playing around with a resumé design is only for people who can't come up with a convincing portfolio. Be creative in your works, keep your resumé simple and boring.

September 24, 2010

Setup “monitor” mode and disable CRC checking

1. Live Monitoring and Writing Raw 802.11 Packets — From madwifi README

The driver can be used in a live “monitor” mode, by creating a monitor
VAP and sending packets to it. All packets sent to a monitor mode VAP
will bypass any state machine.

To create a monitor VAP, use:

wlanconfig ath1 create wlandev wifi0 wlanmode monitor
ifconfig ath1 up

Finally, you can choose to receive packets on ath1 in several different
packet formats:

echo ’801′ > /proc/sys/net/ath1/dev_type # only 802.11 headers
echo ’802′ > /proc/sys/net/ath1/dev_type # prism2 headers
echo ’803′ > /proc/sys/net/ath1/dev_type # radiotap headers
echo ’804′ > /proc/sys/net/ath1/dev_type # atheros descriptors

2. Disable CRC and PHY error checking

Allows monitor VAPs to process frames that have been marked
as errors by the hardware. Two new sysctl entries are created,
“monitor_crc_errors” and “monitor_phy_errors”. When these are set
to 1, the monitor mode interface will pass through frames that have
been marked with HAL_RXERR_CRC and HAL_RXERR_PHY respectively.
Default is to maintain current behaviour – no rx errors are passed
through.

echo ’1′ > /proc/sys/net/ath1/monitor_crc_errors # Disable CRC error checking

echo ’1′ > /proc/sys/net/ath1/monitor_phy_errors # Disable PHY error checking

some helpful webpages

Good Sites for Researchers and Students (click)

Especially, there are something really worth reading:
Graduate School Survival Guide (click)
Writing Technical Articles (cllick)
Networking on the Network: A Guide to Professional Skills for PhD Student (click)
Useful Things to Know About Ph. D. Thesis Research (click)
Resources for Ph.D. Students (click)
Sources of good advice (click)
So long, and thanks for the Ph.D. (for cs major) (click)

September 20, 2010

Today's word: tweak

  • Twist or pull (something) sharply
    • he tweaked the boy's ear
  • Improve (a mechanism or system) by making fine adjustments to it
    • engineers tweak the car's operating systems during the race

September 17, 2010

Eclipse, x64 or x86?

64位的系统,才知道自己的浏览器是32位的……谢谢国家,谢谢oracle,谢谢java installer。折腾了半天的64位eclipse,修了这个错修那个错,就如同这个帖子一样(here)。是下面的一个回复帮了我~

Nietvoordekat: "I have a 64 bit Windows 7, didn't check if I had the 32 or 64 bit Java installed. Easy and fast check to do, is whether or not your Java folder is in Program Files or Program Files(x86). If you've got both of these maps and it's in the x86 one, you'll need the 32 bit download. You might wanna move that tip up from the bottom to the top, it shouldn't take more then 10 secs to check."

September 14, 2010

20100914

strcat
save
dlmwrite
some basic sorting algorthms

TODO: ghost and tcpdump.
where the CSI is in the sourcecode.

Days of our lives

Daisypath Anniversary tickers