forAllBright
forAllBright

Reputation: 61

why does it cause error when trying to give the original pointer value a new value?

I am a newbie to C language, I am trying to use pointers as below.

  1. po1 is defined as a pointer which is pointing at an address. The PC allocates 1 byte of memory for it. po2 is the same. I want to get the address of the memory pointed by po2, but only get an unexpected 0, obviously not the address.

    #include <stdio.h>
    int main(int argc, char *argv[]) {
        char *po2, *po1;
        printf("---%d---\n", po2); 
        return 0;
    }
    

    Output is:

    demo11.c:5:23: warning: format specifies type 'int' but the argument has type >'char *' [-Wformat] printf("-****--%d-****--\n", po2); ~~ ^~~ %s 1 warning generated. -****--0-****--

  2. Then I am trying to give the value of foo to the memory po2 is pointing at, but it gives an error.

    #include <stdio.h>
    int main(int argc, char *argv[]) {
        char *po2, *po1;
        char foo = 'D';
        *po2 = foo;
        printf("%c---------------\n", *po2); 
        return 0;
    }
    

    Output is:

    Terminated due to signal: SEGMENTATION FAULT (11)

Obviously, the error is caused by statement *po2 = foo;

Any help would be appreciated, thanks.

Upvotes: 0

Views: 176

Answers (2)

Toby
Toby

Reputation: 10154

  1. You are using the incorrect format specifier within the string in the printf(). the %d is specifically for integers. For a pointer you should use %p.

    Looking at the warning you received you can determine this from this bit: format specifies type 'int' but the argument has type 'char *' which basically means that the format specifier (the %d) indicates an int type variable but you have supplied a char * type.

  2. When you say *po2 = foo; you are actually assigning the value of foo to whatever is pointed at by po2, instead of assigning the address of foo into po2 itself.

    Firstly, when assigning an address to a pointer, do not use the *, so the first part becomes po2 =. Secondly, you want to allocate the address of foo rather than the value it holds, thus you should use the "address-of" operator, that is & so the entire line then becomes po2 = &foo;

    The reason your current code gives a segmentation fault is because, as mentioned your current code assigns the value of foo, to wherever po2 is pointing at. Because the pointer has not been correctly initialized yet, it holds some indeterminate address (usually NULL) that is invalid. Thus when the PC tries to find this invalid address it is trying to find a memory location location that does not exist (e.g. location 0 or location 5 billion, etc). It cannot do this and so it results in a segmentation fault.

You seem to have misunderstood a little bit how pointers work. When you use char *po2;, this creates a variable that holds an address. This is just the same as creating any other type of variable, there is no other memory allocated other than the memory used to hold the address. Because a pointer defined like this is not initialized, it will contain an indeterminate address value. In some situations (but not all) this value will be NULL, or 0, this is why your printf outputs 0 after it gives a warning.

If you would like to have the pointer po2 point at the variable foo then you put the address of foo into the pointer. po2 will hold the address of foo and foo will still hold 'D'. The 'D' is not magically moved to some other part of memory pointed to by po2, it stays right where it is. If you were to use the pointer to change the value of what it is pointing at, then the value in foo would be the value altered.

For example:

char *po2;   // A pointer variable that will hold an address of a char
char foo = 'D'; // A variable that will hold a char
po2 = foo;   // po2 contains a new copy of 'D', this is not what you wanted
po2 = &foo;  // po2 contains address of foo, this is right
*po2 = 'C';  // foo will now contain 'C'
*po2 = foo;  // same as using foo = foo
po2 = 'C';   // po2 contains 'C', this is not what you wanted

Upvotes: 6

Mika Alas
Mika Alas

Reputation: 102

Problem is here:

*po2 = foo;

You need to assign address to pointer po2, not value. In this case you assigned pointer po2 value of variable foo. If you want to assign address do this:

po2 = &foo;

Upvotes: -1

Related Questions