SE250:lab-2:jham005

From Marks Wiki
Jump to navigation Jump to search

John Hamer's lab #2

Pointers are 4 bytes on both the lab PCs and the Linux server. This is the same size as int, long and float on both machines. I had hoped we might see 64-bit (8 byte) pointers on Linux, which should be enabled with the GCC -m64 flag. However, 64-bit support does not appear to be available.

The expression (long)(&x - &y) does the subtraction first, followed by the (redundant) conversion to long. Pointer subtraction in C is defined in terms of the size of the thing pointed at, so the result (1) indicates 1 int (a 4-byte quantity). In contrast, (long)&x - (long)&y is a subtraction of two longs, so no pointer-size scaling is done. The result is the number of bytes (4) between the two addresses.

Declaring a char array between x and y shows that the compiler gets to choose where things actually go, and can decide to allocate more memory between variables than absolutely necessary. There are often (significant) performance advantages in doing this, as modern hardware reads and writes memory in 4 or 8 (or larger) byte blocks.

Arrays are worth a moment of careful thought. Clearly the contents of an array are accessed through a pointer, but the pointer is not actually stored in memory. Rather, an array is a "constant" pointer. You can use arr as a pointer but you cannot change its value, rather like you can use but cannot change the value of the number 3. C treats &arr the same as arr when you use it as a pointer. The array indexing expression &arr[4] is the same as arr + 4 — an address 4 elements past the start of the array.

Care is needed when taking a pointer to a local (auto) variable. Returning a pointer to an auto variable is almost certainly wrong, and will result in unpredictable behaviour.

Structs are blocks of memory, where the components can be individually accessed. The compiler may alignment the components of a struct, e.g. allocating two or even four bytes for a char.

Unions appear like structs, but all the components overlap in memory. The size of a union is the size of the largest component.

Malloc returns a new, unused block of memory (or 0 if memory is exhaused — your programs need to check for this). This memory persists until explicitly released by calling free. Freed memory can be re-used by a subsequent call to malloc.

A function is a constant pointer. Functions typically reside near the area used for static variables.