char *c vs. char c[] 
Author Message
 char *c vs. char c[]

Hi folks, I'm a little perplexed about using pointers to characters.  My
simple program below works fine if I use char data[81], but I can't seem to
get it to work using char *data.  What would I need to do to do this?  The
reason I want to do this is because I don't know the size of what will be
read in in advance (it could be quite large), and allocating a very large
arrary seems wasteful.  I know 81 characters isn't a very large array - this
is just my example to illustrate the point.

p.s. In case you need to know, detail.dat is just a "regular" text file.  It
has several groups of numbers and letters on each line.

--
Ashley Smith

----- begin char.c
#include <stdio.h>

int main(void)
{
 FILE *fp;
 char filename[] = "detail.dat";
        char data[81];    /* how can I get this to work using char *data ?
*/

        if ((fp = fopen(filename, "r")) == NULL)
        {
                fprintf(stderr, "Can't open %s.\n", filename);
                exit(1);
        }

        while (!feof(fp))
        {
              fscanf(fp, "%s", data);
              printf("Read in: '%s'\n", data);
        }

        fclose(fp);

Quote:
}

----- end char.c -----

--



Wed, 30 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]
On Sat, 14 Aug 1999 15:29:14 GMT, "Ashley Smith"

Quote:

>Hi folks, I'm a little perplexed about using pointers to characters.  My
>simple program below works fine if I use char data[81], but I can't seem to
>get it to work using char *data.  What would I need to do to do this?  The
>reason I want to do this is because I don't know the size of what will be
>read in in advance (it could be quite large), and allocating a very large
>arrary seems wasteful.  I know 81 characters isn't a very large array - this
>is just my example to illustrate the point.

>p.s. In case you need to know, detail.dat is just a "regular" text file.  It
>has several groups of numbers and letters on each line.

>--
>Ashley Smith

>----- begin char.c
>#include <stdio.h>

>int main(void)
>{
> FILE *fp;
> char filename[] = "detail.dat";
>        char data[81];    /* how can I get this to work using char *data ?
>*/

You need to allocate memory if you use char *data;

For example
    char buffer[81];
    char *data = buffer;

Not much advance on what you have already, but would be useful if you
had two input lines you wanted to read alternately for example (simply
by saying data = buffer1, then data = buffer2)

    #include <malloc.h>

    char *data;
    data = malloc(81);
    if( data == NULL ) { /* panic */ }

This has the advantage that the parameter to malloc can be a variable,
which would allow you to determine the correct size at run-time.

- Show quoted text -

Quote:

>        if ((fp = fopen(filename, "r")) == NULL)
>        {
>                fprintf(stderr, "Can't open %s.\n", filename);
>                exit(1);
>        }

>        while (!feof(fp))
>        {
>              fscanf(fp, "%s", data);
>              printf("Read in: '%s'\n", data);
>        }

>        fclose(fp);
>}
>----- end char.c -----

--
Steve
--



Wed, 30 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]


Quote:
>int main(void)
>{
> FILE *fp;
> char filename[] = "detail.dat";
>        char data[81];    /* how can I get this to work using char *data ?
>*/

By writing

     char * data_ptr = malloc(81);

But I suspect that that is not what you meant.  arrays and pointers are
in no way equivalent.  In many circumstances the bare name of an array
(or function) is replaced by the compiler by the address of the object.
So when appropriate (which isn't always) when faced with data the
compiler writes code that uses the address of data.  However when
presented with data_ptr it generates code that extracts an address value
from storage (identified as data_ptr).  Before you can extract such an
address you must place the address of some relevant storage in that
pointer.

To confuse the newcomers, C refers to addresses as pointers and it also
refers to variables for storing such addresses as pointers.  In the
above data can degenerate to a pointer (value) while data_ptr can is a
pointer (store) that can contain a pointer (value)

Quote:

>        if ((fp = fopen(filename, "r")) == NULL)
>        {

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Wed, 30 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]

(Steve Critchlow) wrote in comp.lang.c.moderated:

Quote:
> On Sat, 14 Aug 1999 15:29:14 GMT, "Ashley Smith"

> >Hi folks, I'm a little perplexed about using pointers to characters.  My
> >simple program below works fine if I use char data[81], but I can't seem to
> >get it to work using char *data.  What would I need to do to do this?  The
> >reason I want to do this is because I don't know the size of what will be
> >read in in advance (it could be quite large), and allocating a very large
> >arrary seems wasteful.  I know 81 characters isn't a very large array - this
> >is just my example to illustrate the point.

> >p.s. In case you need to know, detail.dat is just a "regular" text file.  It
> >has several groups of numbers and letters on each line.

> >--
> >Ashley Smith

> >----- begin char.c
> >#include <stdio.h>

> >int main(void)
> >{
> > FILE *fp;
> > char filename[] = "detail.dat";
> >        char data[81];    /* how can I get this to work using char *data ?
> >*/
> You need to allocate memory if you use char *data;

> For example
>     char buffer[81];
>     char *data = buffer;

> Not much advance on what you have already, but would be useful if you
> had two input lines you wanted to read alternately for example (simply
> by saying data = buffer1, then data = buffer2)

>     #include <malloc.h>

>     char *data;
>     data = malloc(81);
>     if( data == NULL ) { /* panic */ }

> This has the advantage that the parameter to malloc can be a variable,
> which would allow you to determine the correct size at run-time.

> >        if ((fp = fopen(filename, "r")) == NULL)
> >        {
> >                fprintf(stderr, "Can't open %s.\n", filename);
> >                exit(1);
> >        }

> >        while (!feof(fp))
> >        {
> >              fscanf(fp, "%s", data);
> >              printf("Read in: '%s'\n", data);
> >        }

> >        fclose(fp);
> >}
> >----- end char.c -----

> --
> Steve

Just pointing out:  there is no <malloc.h> header in ANSI/ISO C.  The
malloc() function is prototyped in <stdlib.h> in conforming
implementations.

Jack Klein
--
Home: http://home.att.net/~jackklein
--



Thu, 31 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]

Quote:
> But I suspect that that is not what you meant.  arrays and pointers are
> in no way equivalent.  In many circumstances the bare name of an array

Wait, how come I always thought that arrays are just stack memory allocated
with the name of the array pointing to the first index of the array?

--



Thu, 31 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]

Quote:

>> But I suspect that that is not what you meant.  arrays and pointers are
>> in no way equivalent.  In many circumstances the bare name of an array
>Wait, how come I always thought that arrays are just stack memory allocated
>with the name of the array pointing to the first index of the array?

You were probably told that.  It's not generally true.  If you want
generalities, there's not even a guarantee that there's a "stack" - that's
just a common way of implementing some amount of "temporary" storage.

Read the FAQ for more info, but to summarize, an array is a special kind of
object in C, and the main way it's special is that in most contexts, the name
of the array "decays" into a pointer to its first element.  Arrays need not
be stored in any particular place.  And arrays and pointers are not the same.

If you want to know more, read the FAQ.  If you don't, read the FAQ anyway,
it'll be good for you.

-s
--

C/Unix wizard, Pro-commerce radical, Spam fighter.  Boycott Spamazon!
Will work for interesting hardware.  http://www.plethora.net/~seebs/
Visit my new ISP <URL:http://www.plethora.net/> --- More Net, Less Spam!
--



Thu, 31 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]

comp.lang.c.moderated:

Quote:
> > But I suspect that that is not what you meant.  arrays and pointers are
> > in no way equivalent.  In many circumstances the bare name of an array

> Wait, how come I always thought that arrays are just stack memory allocated
> with the name of the array pointing to the first index of the array?

The C language does not define or require a "stack".  Depending on the
implementation arrays may exist in many different places.  Static
arrays might reside in a different place than automatic arrays and
arrays using memory allocated dynamically by the standard library
functions might be in yet another different place.

In some circumstances the name of an actual array decays into a
pointer to the first element of the array.  This is not true in the
case of the sizeof operator, and you can't assign to an array name but
of course you can to a pointer:

char ca [20] = { 0 };
char *cp = ca;

*ca = 'X'; /* legal */
ca = 'X'; /* not legal */

Jack Klein
--
Home: http://home.att.net/~jackklein
--



Thu, 31 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]

writes

Quote:
>> But I suspect that that is not what you meant.  arrays and pointers are
>> in no way equivalent.  In many circumstances the bare name of an array

>Wait, how come I always thought that arrays are just stack memory allocated
>with the name of the array pointing to the first index of the array?

True as long as you have a very broad understanding of 'stack memory'
but there is much more than this to understanding arrays.  Perhaps this
is a case where too much knowledge of common implementation details
actually leads to misunderstanding.  There are a couple of excellent
chapters on this subject in Peter van der Linden's 'Expert C, Deep C
Secrets'

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Thu, 31 Jan 2002 03:00:00 GMT  
 char *c vs. char c[]

There are two problems: a C pointer misunderstanding and a design problem.

When you say char data[81], you allocate memory for 81 chars.  When
you say char *data, you are allocating some number of bytes to hold
the pointer.  But the pointer doesn't yet point to a meaningful place
in memory, so you can't fscanf into it.

You are hoping that something will magically allocate memory for your
input array, and set the pointer to it, as you call fscanf, but it
doesn't happen.

That's the C pointer problem.

The design problem is how to allocate memory.  Whether you say
data[81] or malloc(81), you're still stuck reading data of unknown
length into a fixed size array.  This has potential for a buffer
overflow unless you are absolutely sure that the line length will
never be greater that 80 characters.

Buffer overflows are perhaps the most common wound through which
viruses enter a computer.

What you need is to add a fancy specifier to fscanf (details left to you)
to limit the amount read.  

Alternatively, I usually code a safe read line using fgets (which
takes a maximum).  malloc a reasonable size buffer.  If it doesn't
fit, realloc and try again.  Iterate until done.  I can discuss details
if there's interest.

Quote:

> Hi folks, I'm a little perplexed about using pointers to characters.  My
> simple program below works fine if I use char data[81], but I can't seem to
> get it to work using char *data.  What would I need to do to do this?  The
> reason I want to do this is because I don't know the size of what will be
> read in in advance (it could be quite large), and allocating a very large
> array seems wasteful.  I know 81 characters isn't a very large array - this
> is just my example to illustrate the point.

> p.s. In case you need to know, detail.dat is just a "regular" text file.  It
> has several groups of numbers and letters on each line.

> --
> Ashley Smith

> ----- begin char.c
> #include <stdio.h>

> int main(void)
> {
>  FILE *fp;
>  char filename[] = "detail.dat";
>         char data[81];    /* how can I get this to work using char *data ?
> */

>         if ((fp = fopen(filename, "r")) == NULL)
>         {
>                 fprintf(stderr, "Can't open %s.\n", filename);
>                 exit(1);
>         }

>         while (!feof(fp))
>         {
>               fscanf(fp, "%s", data);
>               printf("Read in: '%s'\n", data);
>         }

>         fclose(fp);
> }
> ----- end char.c -----

> --


--

--



Sat, 02 Feb 2002 03:00:00 GMT  
 char *c vs. char c[]


[...]

Quote:
> Buffer overflows are perhaps the most common wound through which
> viruses enter a computer.

[...]

The above statement has sat on my screen for half an hour, I've
thought about it a lot, and I'm still puzzled. From the remainder of
his post, it appears that the poster knows what he is talking about.
But the above appears to be total balderdash to me. Is Ken confusing
bugs and viruses, am I missing a joke, or does that actually make
sense?

OK, a little research with deja tells me that Ken has been around for
a good while, and (guessing simply from the groups he posts to) has
expertise in electronics (notably PLD programming) and various
flavours of UNIX, as well as C, of course.
Viruses are a PC problem, for the most part, but hell! I'm not a PC
expert, either (I do embedded control). I still can't understand how
any programmer could think that the above makes sense.

Put me out of my misery, someone. Am I stupid, or is he?

Mark Barratt

--



Sun, 03 Feb 2002 03:00:00 GMT  
 char *c vs. char c[]
The statement is succinct but quite correct. A hacker can overflow a buffer,
cause the recipient program to lose its grip on reality, and then introduce
a stream of his own computer codes to be executed in the breach.

Precisely how one does this is not suitable for a public newsgroup (which is
probably why Mr. Goldman didn't go into detail). But typically the attack
exploits the presence of something like gets(), which is one of the more
dangerous commonly used functions in existence, and the culprit behind
several recent system-vulnerability stories in the press.

--

Paul Lutus
www.arachnoid.com


Quote:



> [...]
> > Buffer overflows are perhaps the most common wound through which
> > viruses enter a computer.
> [...]

> The above statement has sat on my screen for half an hour, I've
> thought about it a lot, and I'm still puzzled. From the remainder of
> his post, it appears that the poster knows what he is talking about.
> But the above appears to be total balderdash to me. Is Ken confusing
> bugs and viruses, am I missing a joke, or does that actually make
> sense?

> OK, a little research with deja tells me that Ken has been around for
> a good while, and (guessing simply from the groups he posts to) has
> expertise in electronics (notably PLD programming) and various
> flavours of UNIX, as well as C, of course.
> Viruses are a PC problem, for the most part, but hell! I'm not a PC
> expert, either (I do embedded control). I still can't understand how
> any programmer could think that the above makes sense.

> Put me out of my misery, someone. Am I stupid, or is he?

> Mark Barratt

> --


--



Sun, 03 Feb 2002 03:00:00 GMT  
 char *c vs. char c[]

Quote:



> [...]
>> Buffer overflows are perhaps the most common wound through which
>> viruses enter a computer.
> [...]

> The above statement has sat on my screen for half an hour, I've
> thought about it a lot, and I'm still puzzled. From the remainder of
> his post, it appears that the poster knows what he is talking about.
> But the above appears to be total balderdash to me. Is Ken confusing
> bugs and viruses, am I missing a joke, or does that actually make
> sense?

Neither one of you is stupid, as far as I can tell.

Buffer overflows provide security holes that have been used to introduce
malicious software onto target computers. The basic technique to to arrange
to get data to overflow past the end of the buffer onto the stack, replacing
the return address to point to some code that is also part of what's loaded
into (and past the end of) the buffer.

The instances I've heard about all involve systems where programs load at
fixed addresses, so the actual location of the stack can be hard-coded in
the malicious program. Thus, this is more common on Unix than Windows, for
example.

    -- Darin
--



Sun, 03 Feb 2002 03:00:00 GMT  
 char *c vs. char c[]

Quote:


>> Buffer overflows are perhaps the most common wound through which
>> viruses enter a computer.


Quote:

>The above statement has sat on my screen for half an hour, I've
>thought about it a lot, and I'm still puzzled. ...
>Put me out of my misery, someone.

An example might serve best to illustrate the problem.

        #include <stdio.h>

        void f(void);

        int main(void) {
                f();
                printf("done\n");
                return 0;
        }

        void f(void) {
                char buf[32];

                printf("enter no more than 31 characters\n");
                fflush(stdout);
                gets(buf);
        }

Suppose you compile this program on an IBM PC and run it.  Suppose
further that whoever controls your input -- perhaps the user ran
"prog < file" rather than typing at it from the keyboard -- enters
more than 31 characters.  Suppose further that (since this is a
PC) the %esp stack pointer inside f() is, say, 0xef74ff90 at entry,
and the actual machine code for f() is:

        f:
                pushl %ebp
                movl %esp,%ebp
                subl $32,%esp
                pushl $.LC0
                call printf
                pushl $__sstdout
                call fflush
                leal -32(%ebp),%eax
                pushl %eax
                call gets
                leave
                ret

Remember, %esp is (for this example) 0xef74ff90; the PC architecture
means that the word at that address is the return address for the
"ret" instruction.  Since f() was called from within main(), that
will be the address of some instruction inside main().

Now since %esp was 0xef74ff90, the first instruction changes it
to 0xef74ff8c, storing the previous %ebp at 0xef74ff8c.  The
next instruction sets %ebp to 0xef74ff8c, and then sets %esp to
0xef74ff8c - 32 or 0xef74ff6c.  (The instructions after that
-- to call printf and fflush -- further modify %esp, but this no
longer really matters.)

This means that the call to gets() passes it the address 0xef74ff6c
(&buf[0]).  Since gets() blithely writes any number of bytes, we
feed it input consisting of, say, 32 'X' characters followed by the
bytes:

        0x90    (a nonprinting character, meta-control-P)
        0xff    ('?')
        0x74    ('t')
        0xef    ('?')

These four bytes are written at 0xef74ff8c (the previous saved
%ebp).  We follow these by some more bytes:

        0x6c    ('l')
        0xff    ('?')
        0x74    ('t')
        0xef    ('?')

and then a newline.  So, gets() overwrites not only the saved %ebp
at 0xef74ff8c, but also the saved return EIP at 0xef74ff90.

Now we return to f() (at the "leave" instruction).  The "leave"
sets %esp to %ebp -- i.e., 0xef74ff8c -- and then pops a word
from this new %esp into %ebp.  Since we just wrote 0xef74ff90
there, this sets both %ebp and %esp to 0xef74ff90.  The CPU
continues on and executes the next instruction, which is "ret".
This pops another word from the stack and sets EIP to that word.
But that word is again one we provided (by overrunning the buffer
handed to gets()), and it is in fact 0xef74ff6c.

        Q: What is stored in memory at 0xef74ff6c?
        A: The 32 'X' characters.

Now suppose instead of 32 'X' characters, we send 32 bytes of code
that implement a virus -- et voila, we have inserted a virus via a
buffer overflow.  ('X', 0x58, is a "pop %eax" instruction, if I
read the table in the book right.)

It takes a lot of work to do this: you have to figure out just
where to put the code and where to set the registers and so on,
and of course this code will only work on one particular architecture
-- sending the same 32 bytes to a SPARC or ARM or Merced or PPC or
some such will not do the trick -- but it is in fact possible.
The "Morris Worm" that ran amok on the Internet in 1988 got in
through the "finger" program this way, by loading VAX code into
the 512-byte buffer and overwriting the stack immediately after
that.  (It never got into any of the U of MD CS VAXen because I
had changed our "fingerd" daemon.  Its other main avenues were
sendmail's "wizard's password" and .rhosts files, neither of which
was a buffer overflow attack.)
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc


--



Sun, 03 Feb 2002 03:00:00 GMT  
 char *c vs. char c[]

Quote:



> [...]
> > Buffer overflows are perhaps the most common wound through which
> > viruses enter a computer.
> [...]

> The above statement has sat on my screen for half an hour, I've
> thought about it a lot, and I'm still puzzled. From the remainder of
> his post, it appears that the poster knows what he is talking about.
> But the above appears to be total balderdash to me. Is Ken confusing
> bugs and viruses, am I missing a joke, or does that actually make
> sense?

I think he meant to say 'crackers' instead of 'viruses'. Taking
advantage of buffer overflows to overwrite part of a process's code
segment, which may then be executed is a relatively common form of
attack into a system.

Adam

--
Apparently [...] police in many lands are now complaining that local
arrestees are insisting on having their Miranda rights read to them,
just like perps in American TV cop shows. When it's explained to them
that they are in a different country, where those rights do not exist,
they become outraged. Starsky and Hutch reruns, dubbed into diverse
languages, may turn out, in the long run, to be a greater force for
human rights than the [United States] Declaration of Independence.
-- Neal Stephenson (Cryptonomicon -
http://www.io.com/~mccoy/beginning_print.html)

----------------
The opinions expressed in this email are mine alone, and do not
neccesarily represent those of my employer, my parents, or the people
who wrote the email software I use.
--



Sun, 03 Feb 2002 03:00:00 GMT  
 
 [ 27 post ]  Go to page: [1] [2]

 Relevant Pages 

1. char **str vs. char *str[]

2. char *line vs. char line[]

3. char *str vs. char str[]

4. char *str vs. char s

5. char *x[] vs. char**

6. A char pointer (char *) vs. char array question

7. char[] vs char * vs #defines for constant strings

8. char * vs char[]

9. char ** vs char * f()

10. char [] vs char *

11. char ** VS char *** ???

12. const char* vs. char *

 

 
Powered by phpBB® Forum Software