Memory allocation

For bytes1[], uint[] etc

For bytes and string arrays

Assembly

library GetCode {
    function at(address _addr) public view returns (bytes o_code) {
        assembly {
            // retrieve the size of the code deployed at _addr, this needs assembly
            let size := extcodesize(_addr)
				    // Loads the free memory pointer (always stored at position 0x40) into o_code.
            o_code := mload(0x40)
            // new "memory end" including padding
            //Updates the free memory pointer to a new location:

						//add(size, 0x20) accounts for the 32-byte length prefix of dynamic arrays.
						//add(..., 0x1f) and and(..., not(0x1f)) rounds up to the nearest multiple of 32 (padding).

            mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
            // Stores the length of the byte array (size) at the beginning of o_code (Solidity dynamic arrays start with a 32-byte length prefix).
            mstore(o_code, size)
						// Copies the actual bytecode at _addr into memory:

						//Starts writing at o_code + 32, skipping over the length prefix.

						//Starts reading code at offset 0 and copies size bytes.
            extcodecopy(_addr, add(o_code, 0x20), 0, size)
        }
    }
}

Round any number to nearest multiple of 32. You do