trying to understand memory (basic)

Started by
8 comments, last by Anthony Serrano 16 years, 9 months ago
I thought I understood how memory worked, and this program contradict my understanding...

#include <iostream>

using namespace std;

int main(void)
{   
int number1; // declare 2 variable of type int (4 bytes).
int number2;  
    
short number3;  // declare 1 variable of type short (2 bytes). 
    
double number4; // declare 3 variable of type double (8 bytes). 
double number5;
double number6;

char letter1;  // declare 1 variable of type char (1 bytes).

cout << &number1 << endl; // print all variables' address.
cout << &number2 << endl;
cout << &number3 << endl;
cout << &number4 << endl;
cout << &number5 << endl;
cout << &number6 << endl;  
cout << &letter1 << endl;  

return 0;
} 
the output on my PC look like this: --------------------------------------------- 0012FF7C 0012FF78 0012FF74 0012FF6C 0012FF64 0012FF5C (and letter1 address have strange symbols...) ---------------------------------------------- First I would like to understand why the address of letter1 doesn't use a normal hexadecimal number. Second I would like to understand why some of the offsets of the memory addresses don't correspond to the data type... for instance, number3 is a short (2 bytes), so why the offset is 4 bytes? Thanks again for helping me understanding basic notions...!
Advertisement
Data structure alignment
Quote:
Second I would like to understand why some of the offsets of the memory addresses don't correspond to the data type...

Alot of compiliers will add padding for speed to your varables. This is
useually, but not always, the size of the data bus width.

For example, on a compilier producing 32 bit code, it will padd
everything on a 4 byte bounderies, unless you explicitly tell it
not to through #pragma or a compilier switch/option.

Quote:
(and letter1 address have strange symbols...)

What do you mean here? Garbage characters?
Quote:
What do you mean here? Garbage characters?


What is address (&c) of "char c"?

Obviously, it's "char *c".

And this is interpreted by cout as null-terminated string. And when you print that out, you get contents of the memory up until first occurance of value of 0. Or you could get a crash.
This is a guess, but why &letter1 is printing strange symbols is that cout is thinking it's a string, not a pointer to a character. Therefore, it interprets the first char (aka: letter1), and then continues on until it gets to a '\0'. During that time it moves into random uninitialized or memory that's been used by other parts of the computer. Most of it isn't meant to be read as characters, so there just random ASCII characters. It's like opening up a random file (say a .exe) with Notepad - you see a bunch of junk because it isn't actually text but it's being interpreted as it.

If you don't already know, this is because in C, strings were defined as an array of chars, which is passed to things just as a poitner to char. So cout sees a pointer to char as a string, not as an integer like the rest of them. Accursed const char* strings! Maybe you could cast it to int to get it to print?

Edit: I was beaten! But Antheus agrees with me, so we're all happy.
Casting to an int will work:
	std::cout << (int*)&letter1 << std::endl;
So, logically, it's pointless to use short types because of data alignment?

What's the purpose of using 'short' if it fills the same amount of space as a normal int type?
Quote:
What's the purpose of using 'short' if it fills the same amount of space as a normal int type?

The size of a data type is system dependent.

A "short" used to be 2 bytes on 32 bit systems, while "int"s
where 4 bytes.
Quote:For example, on a compilier producing 32 bit code, it will padd
everything on a 4 byte bounderies, unless you explicitly tell it
not to through #pragma or a compilier switch/option.


That's incorrect - compilers will by default align data to boundaries of the same size as the datatype.

By that I mean char will be 1-byte aligned, shorts 2-byte aligned, ints 4-byte aligned etc.

I feel also that in the majority of situations, an int will be preferable to a short, as the extra 2 bytes on a modern system is really negligible, unless say allocating say a very large array (even then an array of 1000 elements is still only an extra 2000 bytes of memory, and ints are quicker to process than shorts anyway.

Quote:A "short" used to be 2 bytes on 32 bit systems, while "int"s
where 4 bytes.


What do you mean used to be...? O_o
Quote:Original post by Alpha Brain
So, logically, it's pointless to use short types because of data alignment?

What's the purpose of using 'short' if it fills the same amount of space as a normal int type?


The space savings of using short vs int are highly dependent upon platform, implementation, and usage.

In your code, for example, first you have just a single short sandwiched between variables that are 32-bit aligned, so you're going to have some wasted memory no matter what without forcing the compiler to ignore data alignment.

Secondly, local variables are usually created on the stack. On many 32-bit platforms, stack addresses are always aligned to 32-bit boundaries, regardless of the type's size.

However, there are other situations where using a short instead of an int may save memory (assuming you're on a platform where short and int aren't the same size), for example, when writing binary data to file, when used as members of a class/struct, or when created on the heap (via malloc/new/new[]).

This topic is closed to new replies.

Advertisement