Author |
Message |
Ashley Smit #1 / 27
|
 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 |
|
 |
Steve Critchl #2 / 27
|
 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. 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 |
|
 |
Francis Glassboro #3 / 27
|
 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 |
|
 |
Jack Kle #4 / 27
|
 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 |
|
 |
Lee #5 / 27
|
 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 |
|
 |
Peter Seeba #6 / 27
|
 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 |
|
 |
Jack Kle #7 / 27
|
 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 |
|
 |
Francis Glassboro #8 / 27
|
 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 |
|
 |
kgol #9 / 27
|
 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 |
|
 |
Mark Barrat #10 / 27
|
 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 |
|
 |
Paul Lutu #11 / 27
|
 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 |
|
 |
Darin Adle #12 / 27
|
 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 |
|
 |
Chris Tore #13 / 27
|
 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 |
|
 |
Adam Sprag #14 / 27
|
 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 |
|
|
Page 1 of 2
|
[ 27 post ] |
|
Go to page:
[1]
[2] |
|