LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Why not able to create segmentation fault in second program? (https://www.linuxquestions.org/questions/programming-9/why-not-able-to-create-segmentation-fault-in-second-program-4175729473/)

ajiten 10-02-2023 06:37 AM

Why not able to create segmentation fault in second program?
 
Had posted the below question earlier here, where was advised to post it in a separate thread titled: What is memory-garbage and how to avoid it?
Though am confused as never intended to have the memory garbage as the issue, and assume that @NevemTeve wanted me to use the : free() to free the dynamically allocated memory.

However, the intent of my question was different, as asked about why segmentation fault occurred in one program's running, and not in the other; though both have similar pointer assignment.
The first program (buggy.c) has invalid assignment:
Code:

int *noptr = NULL;
which if would replace by :
Code:

int *noptr;
then no error of 'segmentation fault' would occur; that occurs due to no address assigned to: *noptr, hence any value assignment is causing the given error.

Wanted to create a similar error in the second program (bug_c.c) but could not get the same fault by the code line :
Code:

char *noptr = 'c';
as that now gives error in compilation.
Code:

$ g++ -o bug_c -g bug_c.c
bug_c.c: In function ‘int main()’:
bug_c.c:6:18: error: invalid conversion from ‘char’ to ‘char*’ [-fpermissive]
    6 |    char *noptr = 'c';
      |                  ^~~
      |                  |
      |                  char

The codes for the two files : buggy.c, bug_c.c are given belwo:
buggy.c
Code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
  int *ptr = (int *)malloc(sizeof(int)); //not a memory garbage problem, as this line is not an issue, as can have another version with this line removed, and the for-loop removed; and the entire body of the main() replaced by:
                                          //int i = 5; int * noptr  = NULL;  *noptr = i;
                                          // still the same error of segmentation fault would occur.
                                          // $ ./buggy
                                          // Segmentation fault (core dumped)

  int *noptr = NULL;

  for (int i=0; i<10; i++) {
      if (i == 5) {
        *noptr = i;
      }
      else {
        *ptr = i;
      }
      printf("i is %d\n", i);
  }
}

It gives run-time error of Segmentation fault; after compiling using the command: $ g++ -o buggy -g -Wall buggy.c.
Code:

$ ./buggy
i is 0
i is 1
i is 2
i is 3
i is 4
Segmentation fault (core dumped)

---------------------------------------------------------------
bug_c.c
Code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
  //char *noptr = 'c'; //causes compilation error,
  /*  $ g++ -o bug_c -g bug_c.c
      bug_c.c: In function ‘int main()’:
      bug_c.c:6:18: error: invalid conversion from ‘char’ to ‘char*’ [-fpermissive]
          6 |    char *noptr = 'c';
            |                  ^~~
            |                  |
            |                  char

  though a similar assignment in buggy.c, compiles */

  char *noptr;
  char i = '5';
  *noptr = i;
  printf("i: %c, *noptr:%c", i, *noptr);
}

Due to the modification of the commented code-line, the program executes smoothly:
Code:

$ ./bug_c
i: 5, *noptr:5


NevemTeve 10-02-2023 06:50 AM

Code:

int *noptr;
With this line you will have an uninitialized variable, so its value will be wathever random garbage is in the used memory/register when the function starts running.

Also you seem to think you have a right to get a Segmentation Fault whenever you have some bug. That is a false assumption.

rtmistler 10-02-2023 07:32 AM

Quote:

Originally Posted by ajiten (Post 6456628)
Due to the modification of the commented code-line, the program executes smoothly:
Code:

$ ./bug_c
i: 5, *noptr:5


That's just random luck.

A pointer, is like your finger, point it somewhere. Where it is pointing is the value.

Since you did not initialize the pointer, it's pointing to some arbitrary memory location, where "now" that has a value of '5'.

The problem is, the memory the pointer is located in probably doesn't get changed much unless you run a bunch more programs. The location that pointer, points to, also has that same fortune. So you can run this a lot and still see '5'.

That doesn't mean it is correct.

The fact that you declared a pointer variable reserves space for it on the stack.

The contents of the pointer itself are random unless you initialize it by assigning a valid address for it to point to.

Above where you initialized it to NULL is actually valid in some way. Just that the finger is pointing to 0x00000000 which is an illegal address to try to modify, hence why you get the segmentation violation.

What instead you need is a variable to actually point to.
Code:

int value;
int *noptr = &value;

This is correct.

While your second code doesn't always cause a segment violation, it is far worse, it is modifying memory it has no idea what program owns it,

Back to your finger as a pointer, say you're picking people for a team. If you initialize your finger/pointer, you point to someone you want on your team, and it works correctly. If you initialize your finger to point to nowhere, or an invalid address, your hand locks up saying, "I don't know what to do!" If you initialize you finger/pointer to a random, but fortunately valid address, when you select your team member, you may get "bunny rabbit", "cloud", something valid, but random.
Quote:

Originally Posted by ajiten (Post 6456628)
Code:

char *noptr = 'c';

'c' is not a location, it is a value. A character pointer needs to point to a character variable:
Code:

char myChar = 'c';
char *nopty = &myChar;


ajiten 10-06-2023 06:44 PM

Quote:

Originally Posted by NevemTeve (Post 6456633)
Code:

int *noptr;
With this line you will have an uninitialized variable, so its value will be wathever random garbage is in the used memory/register when the function starts running.

Also you seem to think you have a right to get a Segmentation Fault whenever you have some bug. That is a false assumption.

Request elaboration, as the post #3, by @rtmistler is not clear to me.

NevemTeve 10-06-2023 11:46 PM

Request details: which was the first word you didn't understand?

ajiten 10-09-2023 03:34 AM

Quote:

Originally Posted by NevemTeve (Post 6457430)
Request details: which was the first word you didn't understand?

The part not understood is in the first line, as the rest is a modification of the second program (bug.c) only, i.e.:

That's just random luck.
================================
In fact, you also stated a similar statement as your second line, though in the first line you referred to a different area of 'garbage collection'.

---------------------------------

Want to add that now for the below program, am able to compile, with only a warning:
Code:

warning: initialization of ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
    6 |    char *noptr = 'c';
      |                  ^~~

Program:
Code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
  char *noptr = 'c';
  char i = '5';
  *noptr = i;
  printf("i: %c, *noptr:%c", i, *noptr);
}


pan64 10-09-2023 03:51 AM

you still do not understand what does pointer [type] mean in c. First you must to learn that (not to speak about the syntax of the language). Next you need to understand what is a null pointer and what is a valid pointer. What is an initialized and an uninitialized variable. And after that we can discuss what does segmentation fault mean.
pointers always store a memory location, where the given variable is stored.
https://www.javatpoint.com/c-pointers
https://en.wikipedia.org/wiki/Uninitialized_variable
probably this: https://stackoverflow.com/questions/...t-have-a-value
https://www.geeksforgeeks.org/segmentation-fault-c-cpp/

NevemTeve 10-09-2023 04:06 AM

> Want to add that now for the below program,

Want to add what? Random luck? Undefined behavior?

> am able to compile, with only a warning

That's because variable initialization and assignment are different things, even if they look alike.

Code:

char somechar= 'X';
char *ptr= &somechar; /* initialization of the pointer */

ptr= &somechar; /* assignment to the pointer */
*ptr= 'Y';      /* assignment to pointed character */

Again: take same beginners' C-programming course and/or do the exercises on hackerrank.

dugan 10-09-2023 12:55 PM

Do you not know the difference between a null pointer and an uninitialized pointer?

EDIT: Okay, I'll explain it. Memory is a column in Excel. Nothing is at row zero. A memory address is a row number. Some things you should already know are:
  1. The value of a pointer is a memory address
  2. nothing is at row zero (as I said).
  3. a pointer is a variable, and if you don't specify the value of a variable, then its value is whatever's convenient (effectively, this is random).

So this simply stores the the value zero in the pointer variable:

Code:

int *noptr = NULL;
When you dereference the pointer with the following, and then do an assignment:

Code:

*noptr = i
You're writing the value of i to address zero, where nothing is ever supposed to be stored. The OS detects that and you get a segmentation fault.

If you do this, however:

Code:

int* nopr
Then the value of nopr could be any address.

And then when you do this:

Code:

*nopr = i
You're storing the value of i at that random memory address. This is a bad thing. You might not get a segmentation fault because the OS might not detect it as a problem, but fortunately the compiler does:

Code:

~/Documents/segfault via C v13.2.1-gcc
❯ gcc -Wall bug_c.c
bug_c.c: In function ‘main’:
bug_c.c:19:11: warning: ‘noptr’ is used uninitialized [-Wuninitialized]
  19 |    *noptr = i;
      |    ~~~~~~~^~~
bug_c.c:17:10: note: ‘noptr’ was declared here
  17 |    char *noptr;
      |          ^~~~~


When you got that warning, you should really have fixed it before continuing.

Unfortunately, when I try to explain background basics like this, the response I get is usually that I'm going "off topic" (I have gotten this reaction from two different individuals). I assume this poster will act more maturely than some others have.

rtmistler 10-09-2023 01:16 PM

I concur with the advises of NevemTeve and pan64 to review as many references about C pointers as you can tolerate.

I will also add that "pointers are not easy", and I would also say that the syntax allowances for the C language help to keep it confusing.

It is very possible to write code that has no compilation errors or warnings, but which still has a bug.

dugan 10-11-2023 09:12 AM

Are you familiar with the phrase “undefined behavior”?


All times are GMT -5. The time now is 01:47 AM.