Quick question about SIGSEGV

This is a discussion on Quick question about SIGSEGV within the C Programming forums, part of the General Programming Boards category; So, if I only got the user to input a string, then the value of 'p' wouldn't be read only ...

So, if I only got the user to input a string, then the value of 'p' wouldn't be read only and could be manipulated by reverse?

About pointers. for my purpose, if I declared p as an array with a static-sized buffer (I believe that's what they're called) and then send it down to reverse, it would work. Similarly, if I declared it as a pointer but didn't initialize it with a string literal, it would work?
Please tell me if the above assumptions are correct, althought I'll go to test them myself right now.
BTW thanx for that mini-tutorial, prelude, I'm starting to understand somethings now. Just gotta read some parts over a few times for them to sink in.

If pointers have made you suicidal, you're not alone. But there is no need to hurt yourself. There are people who are willing to help. Just call your local C Crisis Centre and talk to the professtionals there. If you don't have a C3 in your neighborhood, go to the global C3 at www.cprogramming.com . If you're still suicidal, don't lose hope. Gently close your book on C and throw it in the fireplace. If you live in a tower, you can throw it out the window. There, doesn't that feel better?

>So, if I only got the user to input a string, then the value of 'p' wouldn't be read only and could be manipulated by reverse?
It has to do with the type of the string. Basically you have three types of strings from the abstract perspective: String literals are arrays of char, but aren't modifiable. Arrays of char are owned by your process and can be modified unless you qualify them as const. Pointers to dynamic memory are also owned by your process and can be modified unless qualified by const. If you had the user input a string then clearly you have one of the latter two and can pass the string to reverse because to input a string you have to place it in memory and thus that memory has to be modifiable.

>if I declared p as an array with a static-sized buffer (I believe that's what they're called)
>and then send it down to reverse, it would work.
Only if the array contains a valid string, that is, a sequence of characters terminated by '\0'.

>if I declared it as a pointer but didn't initialize it with a string literal, it would work?
I wouldn't bet on it. Pointers must point to something before you can use them, otherwise you're working with a wild pointer and that's undefined behavior.

This code invokes an undefined behaviour. The standard says that you have to provide a valid prototype to any variadic function (such as printf()).
BTW, why did you put the end-of-line character at the beginnig of the line? Sounds crazy, doesn't it ?

...The standard says that you have to provide a valid prototype to any variadic function (such as printf()).
BTW, why did you put the end-of-line character at the beginnig of the line? Sounds crazy, doesn't it ?
...

I don't understand what you mean by "provide a valid prototype to any variadic function. I know printf determines how many arguments it takes based on the first argument.

Secondly, since when is '\n' called end-of-line? '\n' is the newline character and it has nothing to do with the code working or not. It can be used anywhere in a string and starts a new line. end-of-file is EOF and can mark (you guessed it) end of file. It has nothing to do with this programme.

If pointers have made you suicidal, you're not alone. But there is no need to hurt yourself. There are people who are willing to help. Just call your local C Crisis Centre and talk to the professtionals there. If you don't have a C3 in your neighborhood, go to the global C3 at www.cprogramming.com . If you're still suicidal, don't lose hope. Gently close your book on C and throw it in the fireplace. If you live in a tower, you can throw it out the window. There, doesn't that feel better?

>I don't understand what you mean by "provide a valid prototype to any variadic function.printf is declared in stdio.h. If you don't include stdio.h, you must declare printf before you use it. That usually involves something like this:

Code:

int printf(const char *fmt, ...);

Functions that take a variable number of arguments can be difficult at times.

>Secondly, since when is '\n' called end-of-line?
Semantics. It really doesn't matter as long as you know what he's talking about.

>'\n' is the newline character and it has nothing to do with the code working or not.
Quite the contrary. On some systems, interactive prompts may not be displayed before input is required because the buffer isn't flushed. This usually happens on Unix or Linux based systems where the prompt looks like this:

Code:

printf("Do something: ");
/* Get input here */

The solution is to flush the buffer manually either with a trailing newline character in the prompt:

I don't understand what you mean by "provide a valid prototype to any variadic function".<...>'\n' not being 'end-of-line' ...

The automatic promotion rules such as

char -> int
short -> int
float -> double
etc.

only apply if a valid prototype is supplied (the '...' part makes the difference.) If the prototype is not supplied, the behaviour is undefined.

The usual way for *printf() and *scanf() is to include <stdio.h> . My point is that it's not an option.

About the second point, there is a difference between the 'newline character' '\n' or the 'carriage return character' '\n' as they are interpreted in binary mode, and the semantic of the '\n' character in text mode (remember, printf() outpouts to stdout which is a text stream) that really means 'end-of-line' or 'line-separator', whatever the actual characters in the stream ('\n', '\r' or a sequence of them, according to the current operating system).

About the second point, there is a difference between the 'newline character' '\n' or the 'carriage return character' '\n' as they are interpreted in binary mode, and the semantic of the '\n' character in text mode (remember, printf() outpouts to stdout which is a text stream) that really means 'end-of-line' or 'line-separator', whatever the actual characters in the stream ('\n', '\r' or a sequence of them, according to the current operating system).

I fail to see the point of your post, or the previous point you were trying to make.
It doesn't matter in a string where the newline falls. The only thing that it has
any effect on is potential buffer flushing. It also makes absolutely no difference
if you have multiple newlines in a single string. Your point would seem to be that
it is better to do:

However, there is absolutely no difference, other than you calling four function
calls, where as I'd call only a single call. The end result is the same, and it has
absolutely no effect on the output. The only way it could matter, is in the case
Prelude pointed out with it potentially not flushing the buffer.

I fail to see the point of your post, or the previous point you were trying to make.
It doesn't matter in a string where the newline falls. The only thing that it has
any effect on is potential buffer flushing. It also makes absolutely no difference
if you have multiple newlines in a single string. Your point would seem to be that
it is better to do:

However, there is absolutely no difference, other than you calling four function
calls, where as I'd call only a single call. The end result is the same, and it has
absolutely no effect on the output. The only way it could matter, is in the case
Prelude pointed out with it potentially not flushing the buffer.

Quzah.

Agreed, but my point is that the place for an end-of-line indicator is at the end of the line:

Code:

printf ("Hello world!\n");

and not at the beginnig of it:

Code:

printf ("\nHello world!");

It's as simple as that.

Thanks to you, I now understand the reason why so many beginners are used to stick the '\n' at the begin of the line. Its precisely because they are mixing the semantinc of the 'raw' '\n' (new line) and the 'cooked' one (end-of-line).

It probably has to do with its name, rather than it's function. It's called "new line". Thus, from the sound of it, whenever you use it, it should give you a "new line". However, as you pointed out, it's functionallity is that of "end of line" marker.

I suppose they should have really called it "EOL", but then, you and I both know people would confuse it with "EOF" all the time and wonder why their programs break.

For those that don't know, the naming is a hold over from manual typewriter days, where you had two keystrokes to:
1) Drop to a new line. (new line)
2) Return the carraige. (carriage return)

[edit]
Still, it's really just a token for the text processor. As such, it's perfectly valid at the start of a line. It would have the following meaning:

Code:

printf("\nPrompt: ");

Saying: "End the current line, and then display the promp." So really I don't see the problem or even semantical confusion.[/edit]

...
>'\n' is the newline character and it has nothing to do with the code working or not.
Quite the contrary. On some systems, interactive prompts may not be displayed before input is required because the buffer isn't flushed.
...

This reminds me of an old problem I had. I'd written a programme where I put the contents of the main function in a do...while() loop so that the user can be asked to repeat the process or quit. The programme never waited for user input and went on to restart by itself.

Anyhow, the only reason I used \n at the beginning of the string was because of style of the output.

If pointers have made you suicidal, you're not alone. But there is no need to hurt yourself. There are people who are willing to help. Just call your local C Crisis Centre and talk to the professtionals there. If you don't have a C3 in your neighborhood, go to the global C3 at www.cprogramming.com . If you're still suicidal, don't lose hope. Gently close your book on C and throw it in the fireplace. If you live in a tower, you can throw it out the window. There, doesn't that feel better?

OK, now this is it. I can't take this stupidity anymore. I decided to leave the original problem with reverse, hoping that if I read my new book's chapter on pointers, I would understand better. I'm reading Ch5 of K&R The C Programming Language book. For those of you who have it (second ed), on pg. 108 it has a programme that uses the following line.
char *lineptr[MAXLINES];
and then passes this to a function with this declaration:
void writelines(char *lineptr[], int nlines);

yes, stdio.h is included.
The line that I commented out, was giving me this error:
wrong type argument to increment
So, I tried the incremention exactly like the book: I have an array of pointers and I have a loop. I increment the pointer to point at the next string. GUESS WHAT? IT'S GIVING ME THE SAME ERROR!!!!!!!!!!!!
Why can the book write *lineptr++ and why can't I write *pa++???? They are the same thing. The only difference is that the book had the lines in the array input using a readlines() function and I have the lines as string constants. Does this have anything to do with it? how? I don't think this is a problem because I don't change the contents of the strings.

I don't know what to do here anymore: everything I read on pointers, I think I understand. But as soon as I use one in any programme, even in the simplest form, it blows up in my face. Please, someone, help: Cikotic's really going psycho here.

If pointers have made you suicidal, you're not alone. But there is no need to hurt yourself. There are people who are willing to help. Just call your local C Crisis Centre and talk to the professtionals there. If you don't have a C3 in your neighborhood, go to the global C3 at www.cprogramming.com . If you're still suicidal, don't lose hope. Gently close your book on C and throw it in the fireplace. If you live in a tower, you can throw it out the window. There, doesn't that feel better?

pa is an array of pointers to strings. pa itself can not be incremented. pa[0], pa[1], etc can be incremented however. Of if you had

Code:

char **p = pa;

then you could do *p++

I suggest you compile the book's examples without changing them and then run through the program until you understand what they are doing. Then make a small change and repeat. Keeping making small changes until you get a grasp of what is going on.

As for the book's example you quoted:
They declared the array in main() and passed it to the function. Whenever you pass an array to a function it degrades into a pointer. That is why they are able to do the manipulation inside the function and why you aren't able to do the exact same in main()

This reminds me of an old problem I had. I'd written a programme where I put the contents of the main function in a do...while() loop so that the user can be asked to repeat the process or quit. The programme never waited for user input and went on to restart by itself.

Different problem entirely. What was happening in your case (I'd lay money on it) was you'd mixed scanf with some other form of input, and you had a newline left in your input stream from a previous call.