PDA

View Full Version : Best way to initialise the char array


shiva
07-11-2004, 09:14 AM
I like to know the best way of initialising a char array...just have a look at the following options and jusr recommend the best one out this




#define BUF_LENGTH 100

char buffer[BUF_LENGTH]

::memset((void*)&buffer,'\0', sizeof(buffer);
::memset((char*)&buffer,'\0', sizeof(buffer));
::memset(buffer,'\0', sizeof(buffer));
::mesmet((&buffer,'\0', sizeof(buffer));
::bzero(buffer,sizeof(buffer);


I like to know how the compiler differentiates for (&buffer) and (buffer) for the char array.

Thanks in advance
-Shiva

Nope
07-11-2004, 03:21 PM
Beside the typos.. :wink:

First, if you use "&buffer" of any kind as target you don't go for the char
array but for the pointer content of buffer. The right target would be either
just "buffer" (what already is a direct pointer of the first char element) or
use "&buffer[0]".

As you use ::memset() you are rather within a C++ compiler than a C
compiler. It is a bit dangerous to use sizeof in this case. It should work in
your case, as buffer is defined as a char array to begin with, but if you
have a dynamically generated buffer (new, malloc and the like) you would
get the size of the pointer "buffer" (=4 on 32bit systems), not the size of
the array. So if you have the right size with BUF_LENGTH anyway, use it.

I really don't know what's the best way to set an array back to zero. Every
operation of this kind is expensive. Normally you should try to avoid it
alltogether. And, with very few exceptions, you can usually work around
the need to use it.

As an example, if you use such a buffer to read-in a text-line over a
socket or pipe and you want to look between the reads for some kind of
end marker, like ".\n" or "\r\n\r\n" with strstr(), you just set the byte right
behind the last read one to \0.

a=read(socket,buffer+offset,100-offset);
offset+=a;
buffer[offset]=0;
p=strstr(buffer,".\n");
if(p!=0) // found end

RobSeace
07-11-2004, 08:48 PM
To more directly answer your question, I'd say the best/proper
choice out of those listed is:


::memset(buffer,'\0', sizeof(buffer));


Of course, I would drop the "::", because I don't use flaky C++
compilers to compile my C code... ;-)

The one which does a void* cast especially annoys me; that's
one of my pet peeves: people who cast to or from void*... The
entire POINT of void* is to auto-cast for you... There's absolutely
no reason in the world why anyone should ever want to manually
cast to or from void*... It's just a blatently ridiculous concept...
And, I firmly believe that anyone that does it should be beaten
severely every time they do it... ;-)

People who use "&buffer" or "&buffer[0]" instead of just plain old
"buffer" are also pretty high on my list of people who deserve
beatings... ;-) They demonstrate a clear lack of understanding of
the nature of C arrays and pointers... While what they have will
actually work (in the case that "buffer" is truely a char buffer and
not a simple pointer to dynamically allocated memory or something,
anyway), it's merely pointless and needlessly complex and
silly... It'd be similar in style to doing "*(&c)" rather than just using
"c"... It sort of demonstrates that the programmer doesn't quite
grasp just WTF he's doing, and/or doesn't fully understand the
tools he's using... That always makes me wary of any code written
by such a person...

Oh, and the bzero() is just an ancient hold-over, and probably
shouldn't be used by anyone for anything, ever... ;-)

i3839
07-11-2004, 10:26 PM
If buffer is a global variable then it's already zeroed. If you dynamically allocate "buffer" then you can just use calloc instead of malloc to avoid your little dilemma.

Nope
07-11-2004, 11:22 PM
Well, honestly, I have to cast void pointers all the time. Not from char* to
void*, that's automatic, but the other way round. On my g++ compiler I
get the error message "unable to cast from void* to char*, forbidden by
ansi standard", or sth like that. It's also impossible to do even simple math
with a void pointer, the compiler won't let me.

i3839
07-12-2004, 06:17 PM
That's because you use C++.

int main(int argc, char** argv){
void* x;
char* y;
x = argv;
y = x;
return 0;
}
gcc -o x x.cpp
x.cpp: In function `int main(int, char**)':
x.cpp:5: error: invalid conversion from `void*' to `char*'
When the file is named x.c then all works just fine, as it should, but C++ thinks for some weird reason that doing y = (char*) x is safer than just y = x, which of course isn't the case.

Nope
07-12-2004, 06:38 PM
I think that's kinda lived americanism, protect them against themselves
even if they won't let you voluntarily.

Well, i3839, that's exactly my point. It's just that Rob seems to be
obsessed with it and if you use a C++ compiler it's a thing you can't
avoid.

RobSeace
07-12-2004, 08:24 PM
Yes, well, I also think people who use C++ compilers to compile
straight C code should also be beaten severely... ;-)

This IS the "C" forum, after all... We've got a seperate C++ forum...
In there, I wouldn't complain about such stupidity, because there
are far worse attrocities that grate on my nerves far worse than
that when dealing with C++ code... ;-) But, for plain C code, there's
simply NO need for such nonsense... (Of course, there's no need
for it in C++ code either, and the compiler and/or ANSI are just
being insanely over-anal and completely ridiculous, but that's nothing
new really with C++... ;-) The point being, I wouldn't blame the
programmer for such nonsense if they're coding C++... But, if
they're writing C code, then there's no need for it...)

However, the real major annoyance is the casting TO void*, rather
than FROM void*, anyway... Eg: as was done to "&buffer" in the
above examples... That's just plain nonsensical and idiotic in ANY
compiler, I think... But, yet, I do still see people do it sometimes...
Casting FROM void* also annoys me (in C code), but I consider
it a much lesser offense... ;-)

Nope
07-12-2004, 09:10 PM
The need to cast voids annoys the hell out of me too. You are right, this is the C forum, but as the multiple "::" suggest it's C++ code anyway.

i3839
07-12-2004, 09:28 PM
Whoa! Now I get a beating because I wanted to show Nope that it's his C++ usage that's to blame? The whole point was that it's plain C code, C++ people shouldn't use void* pointers at all anyway, they should stick to their abstract classes, inheritance and templates instead.

Idle thought: How fast would Nope's server be when written in C instead of C++?

Nope
07-13-2004, 12:08 AM
rofl.

Nobody is beating you i3839. It's just a discussion about totally OT stuff
and if anybody is, then I am the target... :wink:

How fast would it be... Basically it wouldn't run at all. Most of the stuff I've
done wouldn't be practical without classes. Possible of course, but I am not
masochistic enough to write sth like that in C. Btw, I've just upgraded my web located server to use a 2.6 kernel and I installed a beta of my mTVS (2.0.880) on it.

shiva
07-13-2004, 08:26 AM
Thanks to you all, I'm with Rob, what he has mentioned about memset is correct...I too recommend


memset(buffer,'\0',sizeof(buffer)


It's my typo...used "::"..Pl regret me.

As you all said...we should beat people who ever uses "&buffer" and casting it to (void*)....unncessarily creating a burden to compiler...since it already taken care by itself.

Moreover "buffer" and "&buffer" is going to be same...has poor readability when we implement in code.

Always recommended to use the base address like "buffer" itself.

RobSeace
07-13-2004, 06:18 PM
Whoa! Now I get a beating because I wanted to show Nope that it's his C++ usage that's to blame?


Nah, i3839, I make exceptions for such deliberately stupid things
done purely for the purpose of demonstrating the stupidity of
doing it that way... ;-) It's the people who don't know any better
than to actually do things that way in real-life code who deserve
the beatings... ;-)


we should beat people who ever uses "&buffer" and casting it to (void*)....unncessarily creating a burden to compiler


Well, not so much a burden to the compiler, but a burden to the
programmer, and especially to all later programmers who have to
deal with that code in the future... I really don't give half a damn
about how much burden is placed on the compiler; that's its job:
to bear the burden of doing obnoxious little things that I, the
programmer, shouldn't have to deal with... ;-) But, I definitely care
when unnecessary burden is placed on the programmer... And,
not just the dimwit who first wrote things that way, but all those
poor souls who come after him to maintain the code... ;-) And,
silly nonsense like casting to void* or doing &buffer or &buffer[0]
are not only ugly and pointless, but only serve to obfuscate the
code, making it harder to read and comprehend...

mlampkin
07-21-2004, 05:06 AM
Just a technical note about memset....

The second parameter is an integer... not a character... though only the lowest 8 bits of the value are used by the function...

Michael

RobSeace
07-21-2004, 12:47 PM
Yep, which is why I always like to use char constants, rather
than, eg: integer 0 or something... Because, anything other than
an 8-bit value is nonsensical, despite what the stupid prototype
says... ;-) That's just a hold-over from ancient times, I suspect...
Of course, in MANY functions ints and chars are treated pretty
much interchangably... And, of course, no C compiler worth a
damn would ever complain about using a char in place of an int,
since that's always been legal auto-up-casting...