Reason for Segmentation fault

The following program fails with "Segmentation fault" error message, while I try to run in Ubuntu (Debian) Linux m/c. It is not creating any core file, so I could not cross examine it with the debugger. See the comments for much better understanding. Could any one tell me the exact reason why the program is failing?

int main( ) {
    char *ch; (or) ch = 'A';   // but if it assigned to any string then no segmentation fault
    int *p = (int*) &ch[0];   // or &ch[1], &ch[2], .... ch;      but &ch runs fine
    printf("%c", *p);           // Segmentation Fault: only if you use this print statement
}

It's not clear what your actual code is. If you do not assign a value to the character pointer "ch", then it is pointing to an undefined location in memory and so it is not surprising that this would error. If you assign 'A' to ch, you are assigning the hex value of 'A' to the POINTER, which probably is not pointing to a valid memory location.

Well, i would say you're attempting to print a char from some odd pointer value (ptr on ptr on stack, huh ?) you got from an uninitialized var which is char *ch and ... thus accessing outside your 'legal' space therefore the core.
You attending some security course on coding and braging about it or just goofing around :stuck_out_tongue: lol me just joking

int main( ) {
    ch = 'A';  
 int *p = (int*) &ch[0];

First it wouldn't have compiled.

It would have thrown a compile time error, ' ch ' should be a pointer or an array.

:confused: :eek:

Its not crashing in my system

#include <stdio.h>

int main() {
  char *ch;
  int *p = (int*) &ch[0];
  printf("%c\n", *p);
  return 0;
}

I get

 U

as the output

Then the bit of memory that 'p' ends up pointing to has the contents 0x55.

If you have an uninitialised pointer it is just that, uninitialised, and will have the contents of whatever memory was at that point in the stack. As luck would have it, the &ch[0] did not trap and neither did accessing p.

Yes exactly as you had said.

And with this argument it is not guaranteed that the code would never crash.

To simulate that I could spawn this code between several process so that there could be an instance in the stack frame where there would be no value pointed to by ' p ' and ultimately crashing

You didn't allocate memory to ch.
Try:

int main( ) {
    char *ch = malloc(1); 
    *ch = 'A'; 
    int *p = (int*) &ch[0];   // or &ch[1], &ch[2], �. ch;      but &ch runs fine
    printf("%c", *p);           // Segmentation Fault: only if you use this print statement
}

Just to sidetrack a bit, im aware that

char *ch;
*ch = 'A';

should be the correct way to do the ptr value assignment, however I did a bit of investigating on my own and gcc warned me of a type conversion error (something about from an int ptr to a char)

However, if I do

char *ch;
*ch = "A";

gcc is happy

Is it just me, or you cannot assign char ptrs to a single quote character ?

You need memory allocated to ch, any of the following are valid..

char *ch=malloc(1);
*ch='A';
char *ch=malloc(1);
ch[0]='A';
const char *ch="A";
char ach[1];
char *ch=ach;
ch[0]='A';

you need to understand (a) memory (b) pointers

otherwise move to directly to Java.

Found out another way to do it which sticks strictly to the theory behind pointers

char *ptr;
char c='a';
ptr = &c;

Please feel free correct me if I am wrong, as I want to show that I properly understand pointer theory

Hi,

Agree with what Porter state, it is a good practise to allocate a memory block by using malloc rather than directly referencing the pointer to a hardcoded value, this will created problem during run time althought the code can be compiled.

Cheers

By the way, many Linux distributions disable core file creations by default. Stupid for developers, but safer for users (I guess.)

Try:

ulimit -c unlimited

Before running your program, of course :slight_smile: You should then get a core on a SIGSEGV.

The method I suggested for assigning characters to pointers

char *ptr;
char c='a';
ptr = &c;

compiled and ran fine . So if its working properly, why should I still use the malloc() and free() method to assign and deallocate pointer memory ? Is this due to the greater control one is given in manipulating the memory from the heap ?

What's wrong with this then... (rhetorical)

char *get_string(void)
{
char c='a';
char *p=&c;

      return p;
}

Forgive me, I may be stating the obvious here

p (as in the pointer by itself and not the value being pointed to) is not assigned
the address of c, when in fact it should be.

Ok, so is there something your trying to teach me here ?

Porter

Before my last post, I didnt make an effort to actually test your code segment out for myself and see what was going on. so my bad on that part

However, I did run it just then and it turned out ok. I even ran the debugger and found out that the memory addressess of c and *p were idential after char *p=&c;

Heres the code I typed in (inc. line numbers)

18      char c= 'a';
19      char *ptr = &c;
20      return ptr;

Heres the gdb output at line 20

20      return ptr;

(gdb) print &c
$3 = 0xbffff6b7 "a����q\203\004\b\2008\001@\024�������Wl\003@\001"

(gdb) print ptr
$4 = 0xbffff6b7 "a����q\203\004\b\2008\001@\024�������Wl\003@\001"

So if your code suggestion works fine, then what is wrong with it ?? (Maybe something I missed ?)

Yes, although the code compiles the pointer is to a local variable that will evaporate when the function returns, hence you are returning a pointer to bogus memory. This is where you need to use static or heap memory.

The lesson is you need to be careful how you pass pointers to local variables.

I will look into it myself further

Thanks heaps so far for your insights. Im really learning something

After some testing, Ive reached a conclusion that it comes down to a matter of where you are creating the pointers from

You can get away with

char c='a';
char *ptr=&c;

in main() because both c and ptr will exist as long as the program is being run

If you create pointers elsewhere and wish to return them to main(), the safest and most appropriate way to create them is thru the use of the heap (even though for some odd reason, the code segment above created no dramas when placed in a local func that returned a char ptr)

Thoughts, comments ??