Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
222 views
in Technique[技术] by (71.8m points)

c - Dereferencing this pointer gives me -46, but I am not sure why

This is a program I ran:

#include <stdio.h>

int main(void)
{
    int y = 1234;
    char *p = &y;
    int *j = &y;
    printf("%d %d
", *p, *j);
}

I am slightly confused about the output. What I'm seeing is:

-46 1234

I wrote this program as an experiment and wasn't sure what it was going to output. I was expecting possibly one byte from y.

What is happening "behind-the-scenes" here? How does dereferencing p give me -46?

As pointed out by others, I had to do explicit casting to not cause UB. I am not changing that line from char *p = &y; to char *p = (char *)&y; so that I am not invalidating the answers below.

This program is not causing any UB behaviour as pointed here.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you have something like ,

int x = 1234;
int *p = &x;

If You Dereference Pointer p then it will correctly read integer bytes. Because You declared it to be pointer to int . It will know how many bytes to read by sizeof() operator. Generally size of int is 4 bytes (for 32/64-bit platforms) but it is machine dependent that is why it will use sizeof() operator to know correct size and will read so.

For Your Code

 int y = 1234;
 char *p = &y;
 int *j  = &y;

Now pointer p points to y but we have declared it to be pointer to a char so it will only read one byte or whatever byte char is of . 1234 in binary would be represented as

        00000000 00000000 00000100 11010010

Now if your machine is little endian it will store the bytes reversing them

        11010010 00000100 00000000 00000000

11010010 is at address 00 Hypothetical address, 00000100 is at address 01 and so on.

BE:      00   01   02   03
       +----+----+----+----+   
    y: | 00 | 00 | 04 | d2 |
       +----+----+----+----+


LE:      00   01   02   03
       +----+----+----+----+
    y: | d2 | 04 | 00 | 00 |
       +----+----+----+----+

(In Hexadecimal)

So now if you dereference pointer p it will read only first byte and output will be (-46in case of signed char and 210 in case of unsigned char, according to the C standard the signed-ness of plain char is "implementation defined.) as Byte read would be 11010010(because we pointed signed char(in this case it is signed char).

On your PC negative numbers are represented as 2's Complement so the most-significant bit is the sign bit. First bit 1 denotes the sign. 11010010 = –128 + 64 + 16 + 2 = –46 and if you dereference pointer j it will completely read all bytes of int as we declared it to be pointer to int and output will be 1234

If you declare pointer j as int *j then *j will read sizeof(int) here 4 bytes(machine dependent). Same goes with char or any other data type the pointer pointed to them will read as many bytes there size is of , char is of 1 byte.

As others have pointed, you need to explicitly cast to char* as char *p = &y; is a constraint violation - char * and int * are not compatible types, instead write char *p = (char *)&y.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...