jkuk5046
jkuk5046

Reputation: 91

How is an int data stored on the memory in terms of bits? Is it not right-aligned?

I got really confused while I was trying some things out with fwrite function in C.

I read through the manual of fwrite here http://www.cplusplus.com/reference/cstdio/fwrite/

It says the functions writes the array byte by byte, so I tried to write an array of integers, expecting each integer in the array be split up to 4 characters.

I thought that a bit representation of a value is right-aligned on memory. That is, 98(ascii of 'b') would be stored as

00000000 00000000 00000000 01100010

on the memory. So I expected the fwrite function to write ' ', ' ', ' ', 'b' in the txt file. Instead, it wrote 'b', ' ', ' ', ' '.

I got confused so I tested it again with pointer, hoping my knowledge about memory storage was not wrong and it was only about fwrite function. I made an integer array arr, and put (1<<8)+2, 98 in it.

I used char pointer to split each integer into four bytes. Here's the code.

#include <stdio.h>

int main()
{
    int arr[5]={(1<<8)+2, 98, 'c', 'd', 'e'};
    char *p = (char*)&(arr[0]);

    printf("%d %d %d %d %d %d", arr[0], (int)(*p), (int)(*(p+1)), (int)(*(p+2)), (int)(*(p+3)), (int)(*(p+4)));


    FILE *fp;

    fp = fopen("TestFile2.txt", "a");
    fwrite(arr, sizeof(char), 5, fp);
    fclose(fp);
}

The program printed "258 2 1 0 0 98" on the console, and " b" was written in TestFile2 (exlcluding "s).

In my knowledge, (1<<8)+2 representation in terms of bits is

00000000 00000000 00000001 00000010 so the program should've printed 258 0 0 1 2 0.

The weird thing is that the result is not even left-aligned bit representation of the value either.

How is a value store on the memory bitwise? Is it not like what I thought it is? Or, am I missing something else here?

Any helps would be really appreciated.

Upvotes: 2

Views: 588

Answers (3)

Luis Colorado
Luis Colorado

Reputation: 12668

There's no such concept as "right alignment" in memory storage. Only big endian (meaning most significant byte is stored in the lower addressed memory while the least significant byte is stored in the higher addressed memory) and little endian (least significant byte stored in the lower addressed memory and the most significant byt stored in the highest addressed memory)

The order of bits in a byte is a different thing. I've seen books where bits are number from 1 to 8, from higher to lower weight in the byte, and others where the bits are number from 0 to 7 by their weights in the word. Another issue is how are the individual bits in a word transferred when they are serialized to go on the net. some protocols transmit least significant bit firs (mainly rs-232c and ethernet) while others transmit most significant bit first (I think, but I'm not sure, USB and CAN BUS)

if you are using fwrite(2) to write a multibyte int it depends on the machine architecture, to see the order of the bytes actually transferred over the file descriptor. As fwrite() always writes the bytes from lower addressed byte cells to higher, the bytes of the integer will be writen as you write in the paper (most weighted first, then least weighted bytes of the number) only if you are in a big endian machine (sparc, motorolas, and some arms --- in arms, the endiannes is user selectable) but if you are in a little endian machine, then you'll get the bytes with lesser weight first, then the most weighted bytes (e.g. Intel, etc.)

Upvotes: 0

kabanus
kabanus

Reputation: 25895

Looks like you are missing the terminology Endianess. Many systems save their words (4-bytes in a 32-bit system) in "Little Endian" order - that is "little end" first. This means the least significant byte (LSB) is first (lowest address), and it goes up from there. That's why 2 is first (lowest address, LSB) and 1 is second, and then the 0s of the most significant bytes. Endianess is only important when you are manipulating byte level data, but then it is very important to know which endianess your system uses.

Alignment has nothing to do with it - single bytes are always read the same in all systems, like we usually write numbers - LSB on the right.

Upvotes: 4

Sergey Strashko
Sergey Strashko

Reputation: 63

Issue is how you (as human) look at memory, you are caught in trap that memory is displayed in a way 0x0000 0x0001 0x002 for example as memory address(less significant on left), and for you to understand how 4 byte integer is stored in your system do next:

int a=0x01020408;
char* c=(char*)(void*)&a;

And see how it is stored per bytes; most likely it will be c[0]=0x8; c[1]=0x04; c[2]=0x02; Also you can think a bit how processor will load this 4 bytes of memory into register; least significant memory address is loaded into least significant register bits

Upvotes: 0

Related Questions