pointer concepts

K

Keith Thompson

Emmanuel Delahaye said:
Newbie a écrit :

A pointer is just another variable.


Your compiler should complain about that.

The compiler can't complain if it doesn't know what arguments scanf()
expects. The program is missing the required "#include <stdio.h>".

There are a lot of subtleties, some involving the difference between
C90 and C99, but the basic rule is simple: if you're going to use any
functions declared in <stdio.h>, you *must* have a "#include <stdio.h>"
at the top of your program. Your compiler may or may not complain
if it's missing, but it's still mandatory. The same goes for functions
declared in other standard headers (e.g., malloc() in <stdlib.h>).

(Yes, you can theoretically declare the functions yourself, but
there's really no reason to do so.)
 
M

Mark McIntyre

On 9 Feb 2006 22:16:21 -0800, in comp.lang.c , (e-mail address removed)
wrote:

(snip example of potential buffer overrun)
But the codes below works even if you input more than 10 characters?

It probably works in your IDE because you compiled in debug mode ,and
most debuggers catch that sort of error.

Luck. It could also have crashed your computer.

Mark McIntyre
 
B

Barry Schwarz

Hi,

I'm a newbie. I need to clear my pointer concepts.

the code below gives segmentation fault when i use char* str;
int main()
{
char *str;

This pointer doesn't point anywhere yet. You need to assign it the
address of some memory that belongs to you (the address of an object
you define or the address of memory you allocate.
printf("Enter a string to reverse\n");
scanf("%s",&str);

This invokes undefined behavior. The %s requires a char*. You are
passing a char**. Even if it were to work, you would destroy the
nature of str. It is supposed to contain the address of a string, not
the string itself.
strlen(str);

Now strlen will take the data stored in str and treat it as the
address of a string. But it doesn't contain such an address. More
undefined behavior.
}

if I use char str[20] it runs fine.
int main()
{
char str[20];
printf("Enter a string to reverse\n");
scanf("%s",&str);

This has the same problem. The only reason it "works" is because on
your system char* and char(*)[20] have the same size and
representation. Even though the type is wrong, &str also points to
the first char in str.
strlen(str);

Since str is an array and not a pointer, strlen receives the address
of the first char in the array and works as expected.


Remove del for email
 
R

Richard Heathfield

Keith Thompson said:
The compiler can't complain if it doesn't know what arguments scanf()
expects. The program is missing the required "#include <stdio.h>".

I agree that the header is required, but not that the prototype would help a
huge deal in this situation.
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:

I agree that the header is required, but not that the prototype would help a
huge deal in this situation.

Good point.
 
C

Chris Barts

Hi,

I'm a newbie. I need to clear my pointer concepts.

Well, you need to clear your head about what you think you know about
pointers. Most of it is wrong.
the code below gives segmentation fault when i use char* str;

That's lucky. It might have completely hosed your machine. Pointers are
dangerous.

You need headers of some form. Try:

#include <stdio.h> /* For printf and scanf */
#include said:
int main()

You mean int main(void) here.
{
char *str;

Here, str is a location that could hold a pointer to a region of memory if
one is ever assigned to it. It never gets the chance to hold anything
useful.
printf("Enter a string to reverse\n");
scanf("%s",&str);

You are feeding scanf a pointer to the variable str, a pointer to a
pointer to char. A good compiler would warn you about such things.

Secondly, the program would crash even if you had called scanf correctly.
Since str doesn't hold a pointer to any block of memory, scanf would have
tried to put characters into some random location. This is a very good way
to cause very bad things to happen.

Finally, scanf is a bad function to use in this case. The reason is, it
doesn't know when to stop stuffing characters into an area of memory.
scanf will happily overwrite your whole OS and never give you a chance to
stop it. (Modern OSes will protect themselves these days, but scanf could
easily destroy other data you would rather preserve.)
strlen(str);

This function call is quite useless. Not only are you calling it with
bogus data (the random contents of the variable str), but its job is to
compute the length of a string. Calling it without capturing its return
value is pointless.

You should return an int from main, like you said you would above. Try:
return 0;
}

if I use char str[20] it runs fine.

You mean it doesn't crash, even though it should. It still doesn't do
anything sensible.
int main()
{
char str[20];

Here, str is an array of 20 characters. That means you have given the
program a place to put the string you want to type in.
printf("Enter a string to reverse\n");
scanf("%s",&str);

It ought to crash right here. Even better, the compiler should stop and
return an error message. Are you quite sure you know how to operate your
compiler? You are /still/ passing scanf a pointer to a pointer to char,
which isn't what it wants.
strlen(str);
}

Can you please explain why?

Because you need to read a /good/ book on the C language, not whatever
crap you have now. Try "The C Programming Language", Second Edition, by
Brian Kernighan and Dennis Ritchie.
 
K

Keith Thompson

Chris Barts said:
Which part of C89 or C99 mentions a header named cstdio?

I think Richard's point is that "Not C" and "Not defined by the C
standard" are not synonymous. There could very well be an
application-defined or implementation-defined header named cstdio.
(In practice, of course, it's far more likely to be the standard C++
header by that name.)

The statement
foo = 42;
is C, even though the C standard doesn't define anything called "foo".
 
C

Chris Barts

I think Richard's point is that "Not C" and "Not defined by the C
standard" are not synonymous.

I understand that. My point was that the source was so obviously C++ that
his comment seemed inane. It even used I/O streams (the overloaded <<
operator, as I recall).
 
R

Richard Bos

Keith Thompson said:
I think Richard's point is that "Not C" and "Not defined by the C
standard" are not synonymous. There could very well be an
application-defined or implementation-defined header named cstdio.

"cstdio", yes. <cstdio> is more dubious. It _could_ be implementation-
defined, but if so, it's still not C, but C-plus-something. An
application-specific header should be #included using quote marks, not
angle brackets, because it's undefined whether the user can even create
angle bracket headers.
The statement
foo = 42;
is C, even though the C standard doesn't define anything called "foo".

No, but in that case you should be able to point at a spot _in that
application's code_ where it is defined. You can't do that - at least
not portably - with <> headers. With a "" header you may not be able to
tell where it is, but at least you know that there is a place where that
file resides. With a <> header, you don't know even that.

Richard
 
D

Dave Thompson

The compiler can't complain if it doesn't know what arguments scanf()
expects. The program is missing the required "#include <stdio.h>".
Well, it _can_. All library function names are reserved with external
linkage, and the implicit declaration in C89 is as external, so the
compiler "knows" it is the standard function and _can_ check. That
said, if you can't be bothered to invoke the necessary (see next)
declaration(s), why should the compiler do extra work to help you?
It is certainly not _required_ to.
There are a lot of subtleties, some involving the difference between
C90 and C99, but the basic rule is simple: if you're going to use any
functions declared in <stdio.h>, you *must* have a "#include <stdio.h>"
at the top of your program. Your compiler may or may not complain
if it's missing, but it's still mandatory. The same goes for functions
declared in other standard headers (e.g., malloc() in <stdlib.h>).
Very very much _should_ but not actually _must_ in all cases.
(Yes, you can theoretically declare the functions yourself, but
there's really no reason to do so.)

s/the/some of the/; exactly.

- David.Thompson1 at worldnet.att.net
 
D

Dave Thompson

char str[20];

Here, str is an array of 20 characters. That means you have given the
program a place to put the string you want to type in.
printf("Enter a string to reverse\n");
scanf("%s",&str);

It ought to crash right here. Even better, the compiler should stop and
return an error message. Are you quite sure you know how to operate your
compiler? You are /still/ passing scanf a pointer to a pointer to char,
which isn't what it wants.
No. An array (like str) evaluates to a pointer, but &array is not a
pointer to pointer, rather a pointer to array (as opposed to element)
which in theory can have a different representation but in practice
doesn't (and thus 'accidentally' works). FAQ 6.12, 6.13.

- David.Thompson1 at worldnet.att.net
 

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

Forum statistics

Threads
474,175
Messages
2,570,944
Members
47,491
Latest member
mohitk

Latest Threads

Top