Character arrays

A

Anitha

Hi

I observed something while coding the other day:

if I declare a character array as char s[0], and try to use it as any
other character array..it works perfectly fine most of the times. It
holds strings of any length. I guess what is happening here is that
this array initially holds only '\0' and hence is of length 1.

But sometimes, when I tried to write some functions and do some
manipulations on such character arrays, the behavior is erratic..they
result in segmentation fault sometimes,when I try to store certain
values.

I am not able to understand why these arrays are behaving like
this..can you explain how these arrays grow and what could be
happening?

Thanks
Anitha
 
F

Flash Gordon

On 6 Nov 2004 07:02:49 -0800
I observed something while coding the other day:

if I declare a character array as char s[0], and try to use it as any
other character array..it works perfectly fine most of the times. It
holds strings of any length. I guess what is happening here is that
this array initially holds only '\0' and hence is of length 1.

No, it means you are doing something that is not allowed by the standard
AFAIK. You are declaring an array of 0 length. If the compiler allows
this as an extension it is probably actually allowed to do another
trick.
But sometimes, when I tried to write some functions and do some
manipulations on such character arrays, the behavior is erratic..they
result in segmentation fault sometimes,when I try to store certain
values.

I am not able to understand why these arrays are behaving like
this..can you explain how these arrays grow and what could be
happening?

Patient: It hurts when I do this..
Dr: Well, don't do that then.

The array isn't growing. What is happening is that you are overwriting
other data and sometimes not seeing any effect.

If anything "works sometimes" then you are almost always doing something
you should not be doing. If the failure is something like segmentation
faults then you are *definitely* doing something you should not be
doing. If it appears to work but you cannot understand why it works then
it is almost certain to fail at the worst possible time, such as when
your boss is demonstrating it to a VIP.
 
M

Malcolm

Anitha said:
I observed something while coding the other day:

if I declare a character array as char s[0], and try to use it as any
other character array..it works perfectly fine most of the times. It
holds strings of any length. I guess what is happening here is that
this array initially holds only '\0' and hence is of length 1.
The array would be zero bytes in length. However it is highly likely that
the data adjacent to it is zero, hence the illusion of an empty string.

char empty[1] = {'/0'};

is a perfectly unexceptional way of decalring an empty string in C.
But sometimes, when I tried to write some functions and do some
manipulations on such character arrays, the behavior is erratic..they
result in segmentation fault sometimes,when I try to store certain
values.
Because what you are doing is illegal.
I am not able to understand why these arrays are behaving like
this..can you explain how these arrays grow and what could be
happening?
You need to look up pointers. C is not Java, where arrays can be copied from
one to the other and can be null. A C array reserves an area of memory, and
the address cannot be changed. Pointers are used when you want a variable to
be one array sometimes and another array at other times.
 
P

pete

Malcolm said:
Anitha said:
I observed something while coding the other day:

if I declare a character array as char s[0],

There are no zero size objects in standard C.
I'm guessing you are using an extension.

When it works,
it's like parking your car in somebody else's space
when you don't get caught.

If you try to index into memory that is not allocated for your program,
then your code is no longer governed by the rules of C.
Anything can happen. It can work the way you want it to, or not.
 
E

Endymion Ponsonby-Withermoor III

Anitha said:
if I declare a character array as char s[0], and try to use it as any
other character array..it works perfectly fine most of the times. It
holds strings of any length. I guess what is happening here is that
this array initially holds only '\0' and hence is of length 1.

The array only "holds strings of any length" by accident. I don't
know how an array of zero elements is supposed to behave and I don't
know how it actually does behave on your system. The behavior
that you experience is almost certainly due to your overwriting
variables that follow it.
But sometimes, when I tried to write some functions and do some
manipulations on such character arrays, the behavior is erratic..they
result in segmentation fault sometimes,when I try to store certain
values.

I am not able to understand why these arrays are behaving like
this..can you explain how these arrays grow and what could be
happening?

These arrays do not grow at all. Unless you do dynamic allocation, their
size is fixed for as long as the array's lifetime. You should not be writing
outside the array's bounds at all.

Richard [in PE12]
 
A

Anitha

Thanks for all your messages.
I was just fiddling with my code and I wanted to know the reason why I
could declare char str[0]...Anyways, learnt that I shouldnt do what I
am not supposed to do !! :)
But, compiler's indifference to such a declaration is surprising..
I think it is due to the fact that there is no array bound checking in
C...

Anitha Adusumilli
 
E

Endymion Ponsonby-Withermoor III

Anitha said:
Thanks for all your messages.
I was just fiddling with my code and I wanted to know the reason why I
could declare char str[0]...Anyways, learnt that I shouldnt do what I
am not supposed to do !! :)
But, compiler's indifference to such a declaration is surprising..
I think it is due to the fact that there is no array bound checking in
C...

It goes a lot deeper than that. C will allow you to do lots of
things that can bugger things up. It's that sort of language.
If you want all the featherbedding of modern language, read no
further: C is not for you.

Richard [in PE12]
 
R

Richard Bos

I was just fiddling with my code and I wanted to know the reason why I
could declare char str[0]...Anyways, learnt that I shouldnt do what I
am not supposed to do !! :)
But, compiler's indifference to such a declaration is surprising..
I think it is due to the fact that there is no array bound checking in
C...

No, I don't think so. This _is_ an error in C; with the warning level
turned up to "useful", your compiler really should have warned you. I
think it's more likely to go unnoticed because you use a compiler which
comes with a whole metric shitload of embrace-and-extend bags-on-the-
side, and the warning level set to "catatonic" by default. At a guess,
either M$VC or gcc.

Richard
 
M

Michael Mair

Hello Richard,

Richard said:
I was just fiddling with my code and I wanted to know the reason why I
could declare char str[0]...Anyways, learnt that I shouldnt do what I
am not supposed to do !! :)
But, compiler's indifference to such a declaration is surprising..
I think it is due to the fact that there is no array bound checking in
C...


No, I don't think so. This _is_ an error in C; with the warning level
turned up to "useful", your compiler really should have warned you. I
think it's more likely to go unnoticed because you use a compiler which
comes with a whole metric shitload of embrace-and-extend bags-on-the-
side, and the warning level set to "catatonic" by default. At a guess,
either M$VC or gcc.

Yep, I do not understand why they do not use the "useful" warning
level by default -- the users rather find the "switch naughty warnings
off"/"catatonic" mode than the other way round.
And for the huge projects where you cannot do without collecting
warnings, you usually have makefiles.

For my last C course I demanded "gcc -Wall -std=c99 -pedantic" or
"gcc -Wall -ansi -pedantic" from my students but they still did not
get it into their heads that this should be the usual way to call it
-- it has too many parameters...
Next time I'll do an introduction to the shell, let them have
something along the lines of a build script, maybe
____~/bin/build____
#!/bin/sh
gcc -Wall -std=c99 -pedantic -o $* "${1}.c"
___________________

and hope that they get it then with only having to type
"build helloworld" or "build factor -lm". But I fully expect to be
disappointed... ;-)


Cheers
Michael
 
C

Chris Croughton

For my last C course I demanded "gcc -Wall -std=c99 -pedantic" or

I use -W as well, it catches a few more warning cases (comparing
unsigned values as < or <= zero, a < b < c (one it actually caught the
other day, I'd deleted too many characters), unused arguments). They
aren't essential for ANSI but they can show up errors (or things which
need implementing, like using the function arguments).
"gcc -Wall -ansi -pedantic" from my students but they still did not
get it into their heads that this should be the usual way to call it
-- it has too many parameters...

That's what make is for...
Next time I'll do an introduction to the shell, let them have
something along the lines of a build script, maybe
____~/bin/build____
#!/bin/sh
gcc -Wall -std=c99 -pedantic -o $* "${1}.c"

Introduce them to make?

Chris C
 
J

J.L.Cooper

Next time I'll do an introduction to the shell, let them have
Introduce them to make?

It would be really good if students were all introduced to GCC, Make and of
course the all important source control (CVS , RCS or whatever your
favourite is) .
 
D

Dan Pop

In said:
For my last C course I demanded "gcc -Wall -std=c99 -pedantic" or

Why recommend your students to use gcc in a non-conforming mode?
"gcc -Wall -ansi -pedantic" from my students but they still did not

Without -O, -Wall is partially crippled, because gcc doesn't perform
enough data flow analysis to even attempt to detect the usage of
uninitialised variables:

fangorn:~/tmp 538> cat test.c
#include <stdio.h>

int main(void)
{
char *s;
puts(s);
return 0;
}
fangorn:~/tmp 539> gcc -Wall test.c
fangorn:~/tmp 540> gcc -Wall -O test.c
test.c: In function `main':
test.c:5: warning: `s' might be used uninitialized in this function

On x86 hardware, you also want -ffloat-store if standard conformance is
your goal (it doesn't fix all the floating point conformance related
problems of gcc, but it helps a lot). OTOH, if execution speed is more
important than getting the exact precision specified by the standard
(without -ffloat-store you get more than that), you don't want
-ffloat-store.
get it into their heads that this should be the usual way to call it
-- it has too many parameters...

This is what shell aliases are for:

alias c90 gcc -Wall -O -ansi -pedantic
alias brokenc99 gcc -Wall -O -std=c99 -pedantic

does the right thing for csh and friends.

Dan
 
D

Dan Pop

In said:
I use -W as well, it catches a few more warning cases (comparing
unsigned values as < or <= zero, a < b < c (one it actually caught the
other day, I'd deleted too many characters), unused arguments). They
aren't essential for ANSI but they can show up errors (or things which
need implementing, like using the function arguments).

-W complains far too often about perfectly good code, which is why its
warnings haven't been included in -Wall in the first place. It's fine
for people who understand the underlying issues and agree with the right
coding style needed for avoiding them, but I wouldn't recommend it to
any novice (who's prone to use casts in order to shut up the -W messages).

Dan
 
D

Dan Pop

In said:
It would be really good if students were all introduced to GCC, Make and of
course the all important source control (CVS , RCS or whatever your
favourite is) .

But only *after* graduating their C courses. None of these tools, except
gcc, of course, is needed by the C newbie, who is already overwhelmed by
the C language issues. No point in making his life even harder by
exposing him to tools like make and CVS, for which he has no need, yet,
anyway.

Dan
 
J

J.L.Cooper

But only *after* graduating their C courses. None of these tools, except
gcc, of course, is needed by the C newbie, who is already overwhelmed by
the C language issues. No point in making his life even harder by
exposing him to tools like make and CVS, for which he has no need, yet,
anyway.

To me it seems more logical to introduce the students to them at the start
of their course. After all RCS/CVS can be used to source code control any
files being worked on and Make can be used to do a lot more than compile C
programs.

In fact I use RCS and Make a lot more than I use C even my Thesis is stored
in RCS and has a make file. After all C should not be the first module that
a student undertakes, there some which are more important (like Logic,
Computer Architecture and Assembly Language, of course this only my opinion
and I am sure other peoples will differ).
 
C

Chris Croughton

To me it seems more logical to introduce the students to them at the start
of their course. After all RCS/CVS can be used to source code control any
files being worked on and Make can be used to do a lot more than compile C
programs.

Indeed, and make can be used with any language. Or text, for that
matter, especially if they are using a text build tool like TeX.
In fact I use RCS and Make a lot more than I use C even my Thesis is stored
in RCS and has a make file. After all C should not be the first module that
a student undertakes, there some which are more important (like Logic,
Computer Architecture and Assembly Language, of course this only my opinion
and I am sure other peoples will differ).

I agree, I use RCS for text files as well. C is not a good first
language (or the best for many purposes, I use AWK and C++ as much), the
principle of programming should be learnt first and then a number of
languages presented with their good and bad qualities. The environment,
however, will stay useful...

Chris C
 
H

Herbert Rosenau

But only *after* graduating their C courses. None of these tools, except
gcc, of course, is needed by the C newbie, who is already overwhelmed by
the C language issues. No point in making his life even harder by
exposing him to tools like make and CVS, for which he has no need, yet,
anyway.

At that day you tells the students how to use hader files you should
start to introduce them the minimal basic knowledges of make too.

This will give you more time to tell about the traps C holds, tell
more details how to get a standard copilant program wriiten, how to
......

Telling 10 minutes about make and the importance of using the compiler
flags in the right manner increases the knowledge of the students
about C more as saving this short time because you gets more time to
speak about that.
 
A

Arthur J. O'Dwyer

But only *after* graduating their C courses. None of these tools, except
gcc, of course, is needed by the C newbie, who is already overwhelmed by
the C language issues. No point in making his life even harder by
exposing him to tools like make and CVS, for which he has no need, yet,
anyway.

That's assuming that the C newbie is also a newbie to programming and to
*nix as well. Which might be a good assumption in general, I suppose.
But I basically learned CVS this semester, in the same class for which
I learned OCaml... so I have no doubt that a student in a C-newbies course
who already knew the basics of programming in a language like Pascal or
Java could deal with learning both C and the basic Unix tools at the same
time.

my $.02,
-Arthur
 
M

Michael Mair

Dan said:
Why recommend your students to use gcc in a non-conforming mode?

Because we cannot afford the Comeau compiler plus Dinkumware libraries.
Because I hope that in the long run this is the better course than
teaching only C89 and doing C99 as add-on at the end, if at all, and
many useful constructs can be used already.
If every C course did this, then there would be enough weight to get
full conformance not only in gcc but in most and eventually all
major compilers.
However, I fear that in the long run we will get C89 plus C99
standard library and nothing more.

Without -O, -Wall is partially crippled, because gcc doesn't perform
enough data flow analysis to even attempt to detect the usage of
uninitialised variables:
[snip: example uninitialized pointer]

Thank you! This is a really useful suggestion. I will have to read up on
this in the compiler manual to be sure what is all affected but will do
so before the next course :)

On x86 hardware, you also want -ffloat-store if standard conformance is
your goal (it doesn't fix all the floating point conformance related
problems of gcc, but it helps a lot). OTOH, if execution speed is more
important than getting the exact precision specified by the standard
(without -ffloat-store you get more than that), you don't want
-ffloat-store.

Yep, I know. I included into my homework exercises the calculation of
*_EPSILON (* in {FLT,DBL,LDBL}) and address this issue there for
DBL_EPSILON.

This is what shell aliases are for:

alias c90 gcc -Wall -O -ansi -pedantic
alias brokenc99 gcc -Wall -O -std=c99 -pedantic

does the right thing for csh and friends.

I know -- as I mentioned, I do a little introduction to the shell.
There, aliases are, of course, also included. The build script
addresses in addition the usual problem with the -o option which
in turn gives me opportunity to tell something about paths (the
difference between entering "test" and "./test".

Thank you very much for your answer!


Cheers
Michael
 
M

Michael Mair

Chris said:
On Tue, 09 Nov 2004 15:23:06 +0100, Michael Mair


I use -W as well, it catches a few more warning cases (comparing
unsigned values as < or <= zero, a < b < c (one it actually caught the
other day, I'd deleted too many characters), unused arguments). They
aren't essential for ANSI but they can show up errors (or things which
need implementing, like using the function arguments).

For -W, you need to know too much. This is an option I tell
them about but usually the introduction to splint helps them
more.

That's what make is for...

Definitely! But I prefer teaching them the language to a point where
they can appreciate make before introducing them to it.

Introduce them to make?

Already happens. ar, make, gprof, cvs and other come in towards the end
of my course. When they have learned to write complex code which
justifies it. In the long run, the tools are more important than the
language used, but most of them do not even know "that computers can
have command lines" when they enter the course.
Make is definitely too much for absolute beginners. They first have
to really understand (by "menial labour" with an actual language at
"actual" problems) why they need it.
Aliases (as Dan Pop suggested) or this script is quite enough at the
start.


Cheers
Michael
 

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
474,154
Messages
2,570,870
Members
47,400
Latest member
FloridaFvt

Latest Threads

Top