0

In the following two pieces of code, I don't get why the latter one gives a segmentation fault. I apparently wrongly assume that I'm passing an address in both cases... A pointer is an address right?

So this one works:

#include<iostream>
using namespace std;
int test(char *a) {
        *a = *a + 15;
        return 0;
}
int main() {
        char b;
        b = 'c';
        cout << b;
        test(&b);
        cout << b;
}

It outputs:

r

But this one gives segmentation fault, why?:

...

int test(char *a) {
        *a = *a + 15;
        return 0;
}

int main() {
        char *b;
        *b = 'c';
        cout << b;
        test(b);
        cout << *b;
}
Niels
  • 537
  • 5
  • 22
  • 3
    In the second example the variable `b` is a pointer. But when you dereference it, *where does it point?* Remember that uninitialized local variables really are uninitialized. – Some programmer dude Mar 05 '19 at 09:47
  • So how would I initialize it and then point it to one character? I mean without a second variable. I understand I can do char b = 'c' and then char *d = &b, but that would give me the same as in the upper example... – Niels Mar 05 '19 at 09:50
  • It will work if you write: `char a= 'c'; char *b; b = &a;` – Paul Ogilvie Mar 05 '19 at 09:55
  • 1
    What else would you do? If you have a pointer it *must* point somewhere valid for you to be able to dereference it. – Some programmer dude Mar 05 '19 at 10:00
  • 1
    Your code is C++ not C. – fnisi Mar 05 '19 at 10:04

5 Answers5

2

Because memory for b isnt allocate here:

char *b;

Examples works:

char *b = (char*)malloc(sizeof(char));
*b = 'a';
char a = 'a';
char *b = &a;
//C++ only
char *b = new char[1];
*b = 'a';
Igor Galczak
  • 142
  • 6
0

But this one gives segmentation fault, why?

b - it is a pointer to address in memory. In line *b = 'c'; you are assigning to not initialized area some value. To avoid it you should understand that before to assign any value in pointer you should initialize refer for b.

    char *b;
    /*-------*/
    char bb;
    b = &bb;
    /*-------*/
    *b = 'c';
    cout << b;
    test(b);
    cout << *b;
0

Because defining a pointer does not mean that the memory is allocated for your program.

 char *b;
 *b = 'c';

This is undefined behavior since the pointer can point to anything.

There are two ways to fix this.

char *b;
char ch = 'c';
*b = &ch; // taking the address of ch

Now b is pointing to the statically allocated ch.

There is a way with dynamic allocation.

char *b = malloc(sizeof(char));
*b = 'c';
free(b);
Petar Velev
  • 2,305
  • 12
  • 24
  • You can also sometimes benefit from using your own memory allocation using a large array, search for `obstack`. – yyny Mar 05 '19 at 10:10
0

The problem as @Some programmer dude already mentioned: In the second example the variable b is a pointer and it points to an undefined address. However the best way to declare and initialize a pointer is like this:

char *b = NULL;

In the first example the variable b is saved/lies on the stack. You can use it. On the second example, like mentioned, you have only a pointer. If you want to use a pointer in this context you have two options:

  1. Use a local (stack variable) and assign the address to the pointer like this:

    char a = 'c';
    char *b = &a;
    
  2. Use the heap. So get memory from the heap to use your char-pointer. This means the char-pointer points to an address on the heap:

    char *b = malloc(sizeof(char) * 1); // allocate space on the heap
    b[0] = 'c' // or *b = 'c'
    ... // do some stuff and then
    free(b); // don't forget to free your allocated space
    
Mosa
  • 373
  • 1
  • 14
0

In C and C++, declaring a pointer does not mean that the variable points to a valid memory address. Think a pointer as an address card, the sole purpose of it is telling you the address of a memory block (in heap).

It is your responsibility to make sure that address pointed by your pointer variable is a valid memory block. How do you make a memory block a valid allocated space? Well, you use one of the malloc family functions or the new keyword (C++ only).

char *c; // Just an address somewhere
c = malloc(10); // Now, the address pointed by c is a 10 byte long memory block
.....
.....

free(c); // return the allocated memory to OS when you are done

In your code, you do not allocate memory for your pointer. Where does it point to? Is the address pointed by your uninitialised pointer variable a valid memory block? No.

fnisi
  • 1,181
  • 1
  • 14
  • 24