| advertise add site services publishers database health videos | ![]() | about toolbar stats live show health store more stuff JOIN/LOGIN |
Electrotherapy, Electro Acupuncture, Pointer Pulse, Pointer Plus, Home accesshealth.com.au | Geometric Data Hemastainer, Geometric Data Automatic Slide Stainer,... blockscientific.com | Clinical Data Management | Data Management Services | Richmond... rpldatamanagement.com | Reliable Data and Independent Analysis for the Healthcare Industry |... onpointhealthdata.org |
In computer science, a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address. For high-level programming languages, pointers effectively take the place of general purpose registers in low level languages such as assembly language or machine code—but, in contrast, occupies part of the available memory. A pointer references a location in memory, and obtaining the value at the location a pointer refers to is known as dereferencing the pointer. A pointer is a simple, less abstracted implementation of the more abstracted reference data type (although it is not as directly usable as a C++ reference). Several languages support some type of pointer, although some are more restricted than others. Pointers to data significantly improve performance for repetitive operations such as traversing strings, lookup tables, control tables and tree structures. In particular, it is often much cheaper in time and space to copy and dereference pointers than it is to copy and access the data to which the pointers point. Pointers are also used to hold the addresses of entry points for called subroutines in procedural programming and for run-time linking to dynamic link libraries (DLLs). In Object-oriented programming, pointers to functions are used for binding methods, often using what are called virtual method tables. While "pointer" has been used to refer to references in general, it more properly applies to data structures whose interface explicitly allows the pointer to be manipulated (arithmetically via pointer arithmetic) as a memory address, as opposed to a magic cookie or capability where this is not possible.[citation needed] Because pointers allow both protected and unprotected access to memory addresses, there are risks associated with using them particularly in the latter case. For general information about references, see reference (computer science). [edit] Formal descriptionIn computer science, a pointer is a kind of reference. A data primitive (or just primitive) is any datum that can be read from or written to computer memory using one memory access (for instance, both a byte and word are primitives). A data aggregate (or just aggregate) is a group of primitives that are logically contiguous in memory and that are viewed collectively as one datum (for instance, an aggregate could be 3 logically contiguous bytes, the values of which represent the 3 coordinates of a point in space); when an aggregate is entirely composed of the same type of primitive, the aggregate can be called an array; in a sense, a multi-byte word primitive is an array of bytes, and some programs use words in this way. In the context of these definitions, a byte is the smallest primitive; each memory address specifies a different byte. The memory address of the first byte of a datum is considered the memory address (or base memory address) of the entire datum. A memory pointer (or just pointer) is a primitive, the value of which is intended to be used as a memory address; it is said that a pointer points to a memory address. It is also said that a pointer points to a datum [in memory] when the pointer's value is the datum's memory address. More generally, a pointer is a kind of reference, and it is said that a pointer references a datum stored somewhere in memory; to obtain that datum is to dereference the pointer. The feature that separates pointers from other kinds of reference is that a pointer's value is meant to be interpreted as a memory address, which is a rather 'low-level' concept. References serve as a level of indirection: A pointer's value determines which memory address (that is, which datum) is to be used in a calculation. Because indirection is a fundamental aspect of algorithms, pointers are often expressed as a fundamental data type in programming languages; in statically (or strongly) typed programming languages, the type of a pointer determines the type of the datum to which the pointer points. [edit] Quotations
[edit] Use in data structuresWhen setting up data structures like lists, queues and trees, it is necessary to have pointers to help manage how the structure is implemented and controlled. Typical examples of pointers are start pointers, end pointers, and stack pointers. These pointers can either be absolute (the actual physical address or a virtual address in virtual memory) or relative (an offset from an absolute start address ("base") that typically uses less bits than a full address, but will usually require one additional arithmetic operation to resolve). A two-byte offset, containing a 16-bit, unsigned integer, can be used to provide relative addressing for up to 64 kilobytes of a data structure. This can easily be extended to 128K,256K or 512K if the address pointed to is forced to be on a half-word, word or double-word boundary (but, requiring an additional "shift left" bitwise operation—by 1,2 or 3 bits—in order to adjust the offset by a factor of 2,3 or 4, before its addition to the base address). A one byte offset, such as the hexadecimal ASCII value of a character (eg. X'29') can be used to point to an alternative integer value (or index) in an array (eg X'01'). In this way, characters can be very efficiently translated from 'raw data' to a usable sequential index and then to an absolute address without a lookup table. [edit] Use in control tablesControl tables, that are used to control program flow, usually make extensive use of pointers. The pointers, usually embedded in a table entry, may, for instance, be used to hold the entry points to subroutines to be executed, based on certain conditions defined in the same table entry. The pointers can however be simply indexes to other separate, but associated, tables comprising an array of the actual addresses or the addresses themselves (depending upon the programming language constructs available). They can also be used to point (back) to earlier table entries (as in loop processing) or forward to skip some table entries (as in a switch or "early" exit from a loop). For this latter purpose, the "pointer" may simply be the table entry number itself and can be transformed into an actual address by simple arithmetic. [edit] Architectural rootsPointers are a very thin abstraction on top of the addressing capabilities provided by most modern architectures. In the simplest scheme, an address, or a numeric index, is assigned to each unit of memory in the system, where the unit is typically either a byte or a word, effectively transforming all of memory into a very large array. Then, if we have an address, the system provides an operation to retrieve the value stored in the memory unit at that address (usually utilizing the machines general purpose registers). In the usual case, a pointer is large enough to hold more addresses than there are units of memory in the system. This introduces the possibility that a program may attempt to access an address which corresponds to no unit of memory , either because not enough memory is installed (i.e. beyond the range of available memory) or the architecture does not support such addresses. The first case may, in certain platforms such as the Intel x86 architecture, be called a segmentation fault (segfault). The second case is possible in the current implementation of AMD64, where pointers are 64 bit long and addresses only extend to 48 bits. There, pointers must conform to certain rules (canonical addresses), so if a noncanonical pointer is dereferenced, the processor raises a general protection fault. On the other hand, some systems have more units of memory than there are addresses. In this case, a more complex scheme such as memory segmentation or paging is employed to use different parts of the memory at different times. The last incarnations of the x86 architecture support up to 36 bits of physical memory addresses, which were mapped to the 32-bit linear address space through the PAE paging mechanism. Thus, only 1/16 of the possible total memory may be accessed at a time. Another example in the same computer family was the 16-bit protected mode of the 80286 processor, which, though supporting only 16 MiB of physical memory, could access up to 1 GiB of virtual memory, but the combination of 16-bit address and segment registers made accessing more than 64 KiB in one data structure cumbersome. Some restrictions of ANSI pointer arithmetic may have been due to the segmented memory models of this processor family. In order to provide a consistent interface, some architectures provide memory-mapped I/O, which allows some addresses to refer to units of memory while others refer to device registers of other devices in the computer. There are analogous concepts such as file offsets, array indices, and remote object references that serve some of the same purposes as addresses for other types of objects. [edit] UsesPointers are directly supported without restrictions in languages such as PL/I, C, C++, Pascal, and most assembly languages. They are primarily used for constructing references, which in turn are fundamental to constructing nearly all data structures, as well as in passing data between different parts of a program. In functional programming languages that rely heavily on lists, pointers and references are managed abstractly by the language using internal constructs like cons. When dealing with arrays, the critical lookup operation typically involves a stage called address calculation which involves constructing a pointer to the desired data element in the array. If the data elements in the array have lengths that are divisible by powers of two, this arithmetic is usually much more efficient. Padding is frequently used as a mechanism for ensuring this is the case, despite the increased memory requirement. In other data structures, such as linked lists, pointers are used as references to explicitly tie one piece of the structure to another. Pointers are used to pass parameters by reference. This is useful if the programmer wants a function's modifications to a parameter to be visible to the function's caller. This is also useful for returning multiple values from a function. Pointers can also be used to allocate and deallocate dynamic variables and arrays in memory. Since a variable will often become redundant after it has served its purpose, it is a waste of memory to keep it, and therefore it is good practice to deallocate it (using the original pointer reference) when it is no longer needed. Failure to do so may result in a memory leak (where available free memory gradually, or in severe cases rapidly, diminishes because of an accumulation of numerous redundant memory blocks). [edit] C pointersThe basic syntax to define a pointer is int *money; This declares int *money = NULL; If a NULL pointer is dereferenced then a runtime error will occur and execution will stop, usually with a segmentation fault. Once a pointer has been declared, the next logical step is for it to point at something: int a = 5; int *money = NULL; money = &a; This assigns the value of *money = 8; This means take the contents of This example may be more clear if memory is examined directly. Assume that int a = 5; int *money = NULL;
(The NULL pointer shown here is 0x00000000.) By assigning the address of money = &a; yields the following memory values
Then by dereferencing *money = 8; the computer will take the contents of
Clearly, accessing [edit] C arraysIn C, array indexing is formally defined in terms of pointer arithmetic; that is, the language specification requires that int array[5]; /* Declares 5 contiguous (per Plauger Standard C 1992) integers */ int *ptr = array; /* Arrays can be used as pointers */ ptr[0] = 1; /* Pointers can be indexed with array syntax */ *(array + 1) = 2; /* Arrays can be dereferenced with pointer syntax */ *(1 + array) = 3; /* Pointer addition is commutative */ 2[array] = 4; /* Subscript operator is commutative */ This allocates a block of five integers and names the block While most operators on arrays and pointers are equivalent, it is important to note that the Default values of an array can be declared like: int array[5] = {2,4,3,1,5}; If you assume that
Represented here are five integers: 2, 4, 3, 1, and 5. These five integers occupy 32 bits (4 bytes) each with the least-significant byte stored first (this is a little-endian CPU architecture) and are stored consecutively starting at address 0x1000. The syntax for C with pointers is:
The last example is how to access the contents of
E.g. [edit] C linked listBelow is an example of the definition of a linked list in C. /* the empty linked list is * represented by NULL or some * other signal value */ #define EMPTY_LIST NULL struct link { /* the data of this link */ void *data; /* the next link; EMPTY_LIST if this is the last link */ struct link *next; }; Note that this pointer-recursive definition is essentially the same as the reference-recursive definition from the Haskell programming language: data Link a = Nil | Cons a (Link a)
The definition with references, however, is type-checked and does not use potentially confusing signal values. For this reason, data structures in C are usually dealt with via wrapper functions, which are carefully checked for correctness. [edit] Pass-by-address using pointersPointers can be used to pass variables by their address, allowing their value to be changed. For example: /* a copy of the int n is changed */ void not_alter(int n) { n = 360; } /* the actual variable passed (by address) is changed */ void alter(int *n) { *n = 120; } void func(void) { int x = 24; /*pass x's address as the argument*/ alter(&x); /* x now equal to 120 */ not_alter(x); /* x still equal to 120 */ } [edit] Memory-mapped hardwareOn some computing architectures, pointers can be used to directly manipulate memory or memory-mapped devices. Assigning addresses to pointers is an invaluable tool when programming microcontrollers. Below is a simple example declaring a pointer of type int and initialising it to a hexadecimal address in this example the constant int *hardware_address = (int *)0x7FFF; In the mid 80s, using the BIOS to access the video capabilities of PCs was slow. Applications that were display-intensive typically used to access CGA video memory directly by casting the hexadecimal constant #define VID ((unsigned short (*)[80])0xB8000000) void foo() { VID[4][1] = 0x1F00 | 'A'; } [edit] Typed pointers and castingIn many languages, pointers have the additional restriction that the object they point to has a specific type. For example, a pointer may be declared to point to an integer; the language will then attempt to prevent the programmer from pointing it to objects which are not integers, such as floating-point numbers, eliminating some errors. For example, in C int *money; char *bags;
bags = money; because bags = (char *)money; which says to cast the integer pointer of A 2005 draft of the C standard requires that casting a pointer derived from one type to one of another type should maintain the alignment correctness for both types (6.3.2.3 Pointers, par. 7):[3] char *external_buffer = "abcdef"; int *internal_data; internal_data = (int *)external_buffer; // UNDEFINED BEHAVIOUR if "the resulting pointer // is not correctly aligned" In languages that allow pointer arithmetic, arithmetic on pointers takes into account the size of the type. For example, adding an integer number to a pointer produces another pointer that points to an address that is higher by that number times the size of the type. This allows us to easily compute the address of elements of an array of a given type, as was shown in the C arrays example above. When a pointer of one type is cast to another type of a different size, the programmer should expect that pointer arithmetic will be calculated differently. In C, for example, if the Although it is impossible in general to determine at compile-time which casts are safe, some languages store run-time type information which can be used to confirm that these dangerous casts are valid at runtime. Other languages merely accept a conservative approximation of safe casts, or none at all. [edit] Making pointers saferBecause pointers allow a program to access objects that are not explicitly declared beforehand, they enable a variety of programming errors. However, the power they provide is so great that it can be difficult to do some programming tasks without them. To help deal with their problems, many languages have created objects that have some of the useful features of pointers, while avoiding some of their pitfalls. One major problem with pointers is that as long as they can be directly manipulated as a number, they can be made to point to unused addresses or to data which is being used for other purposes. Many languages, including most functional programming languages and recent imperative languages like Java, replace pointers with a more opaque type of reference, typically referred to as simply a reference, which can only be used to refer to objects and not manipulated as numbers, preventing this type of error. Array indexing is handled as a special case. A pointer which does not have any address assigned to it is called a wild pointer. Any attempt to use such uninitialized pointers can cause unexpected behaviour, either because the initial value is not a valid address, or because using it may damage the runtime system and other unrelated parts of the program. The result is often a segmentation fault or storage violation. In systems with explicit memory allocation, it is possible to create a dangling pointer by deallocating the memory region it points into. This type of pointer is dangerous and subtle because a deallocated memory region may contain the same data as it did before it was deallocated but may be then reallocated and overwritten by unrelated code, unknown to the earlier code. It is claimed that languages with garbage collection prevent this type of error (because deallocation is performed automatically) but the pointer itself is not removed by the garbage collector and it may point to irrelevant and unpredictable data if re-used at any time after it has been deallocated. Some languages, like C++, support smart pointers, which use a simple form of reference counting to help track allocation of dynamic memory in addition to acting as a reference. In the absence of reference cycles, where an object refers to itself indirectly through a sequence of smart pointers, these eliminate the possibility of dangling pointers and memory leaks. Delphi strings support reference counting natively. [edit] Null pointerA null pointer has a reserved value, often but not necessarily the value zero, indicating that it refers to no object. Null pointers are used routinely, particularly in C and C++ where the compile-time constant
Since a null-valued pointer does not refer to a meaningful object, an attempt to dereference a null pointer usually causes a run-time error. If this error is left unhandled, the program terminates immediately. In the case of C, execution halts with a segmentation fault because the literal address of In C and C++ programming, two null pointers are guaranteed to compare equal; ANSI C guarantees that any null pointer will be equal to A null pointer should not be confused with an uninitialized pointer: a null pointer is guaranteed to compare unequal to any valid pointer, whereas depending on the language and implementation an uninitialized pointer might have either an indeterminate (random or meaningless) value or might be initialised to an initial constant (possibly but not necessarily In most C programming environments Computer systems based on a tagged architecture are able to distinguish in hardware between a NULL dereference and a legitimate attempt to access a word or structure at address zero. In some programming language environments (at least one proprietary Lisp implementation, for example) the value used as the null pointer (called [edit] Double indirectionIn some languages a pointer can reference another pointer, requiring two dereference operations to get to the original value. While each level of indirection may add a performance cost, it is sometimes necessary in order to provide correct behavior for complex data structures. For example, in C it is typical to define a linked list in terms of an element that contains a pointer to the next element of the list: struct element { struct element * next; int value; }; struct element * head = NULL; This implementation uses a pointer to the first element in the list as a surrogate for the entire list. If a new value is added to the beginning of the list, // Given a sorted list at *head, insert the element item at the first // location where all earlier elements have lesser or equal value. void insert(struct element **head, struct element *item) { struct element ** p; // p points to a pointer to an element for (p = head; *p != NULL; p = &(*p)->next) { if (item->value <= (*p)->value) break; } item->next = *p; *p = item; } // Caller does this: insert(&head, item); In this case, if the value of [edit] Wild pointersWild pointers are pointers that have not been initialized (that is, a wild pointer does not have any address assigned to it) and may make a program crash or behave oddly. In the Pascal or C programming languages, pointers that are not specifically initialized may point to unpredictable addresses in memory. The following example code shows a wild pointer: int func(void) { char *p1 = malloc(sizeof(char)); /* (undefined) value of some place on the heap */ char *p2; /* wild (uninitialized) pointer */ *p1 = 'a'; /* This is OK, assuming malloc() has not returned NULL. */ *p2 = 'b'; /* This invokes undefined behavior */ } Here, [edit] Wild branchWhere a pointer is used as the address of the entry point to a program or start of a subroutine and is also either uninitialized or corrupted, if a call or jump is nevertheless made to this address, a "wild branch" is said to have occurred. The consequences are usually unpredictable and the error may present itself in several different ways depending upon whether or not the pointer is a "valid" address and whether or not there is (coincidentally) a valid instruction (/opcode) at that address. The detection of a wild branch can present one of the most difficult and frustrating debugging exercises since much of the evidence may already have been destroyed beforehand or by execution of one or more inappropriate instructions at the branch location. If available, an instruction set simulator can usually not only detect a wild branch before it takes effect, but also provide a complete or partial trace of its history. [edit] Simulation using an array indexIt is possible to simulate pointer behaviour using an index to an (normally one-dimensional) array. Primarily for languages which do not support pointers explicitly but do support arrays, the array can be thought of and processed as if it were the entire memory range (within the scope of the particular array) and any index to it can be thought of as equivalent to a general purpose register in assembly language (that points to the individual bytes but whose actual value is relative to the start of the array, not its absolute address in memory). Assuming the array is, say, a contiguous 16 megabyte character data structure, individual bytes (or a string of contiguous bytes within the array) can be directly addressed and manipulated using the name of the array with a 31 bit unsigned integer as the simulated pointer (this is quite similar to the C arrays example shown above). Pointer arithmetic can be simulated by adding or subtracting from the index, with minimal additional overhead compared to genuine pointer arithmetic. It is even theoretically possible, using the above technique, together with a suitable instruction set simulator to simulate any machine code or the intermediate (byte code) of any processor/language in another language that does not support pointers at all (for example java / javascript). To achieve this, the binary code can initially be loaded into contiguous bytes of the array for the simulator to "read", interpret and action entirely within the memory contained of the same array. If necessary, to completely avoid buffer overflow problems, bounds checking can usually be actioned for the compiler (or if not, hand coded in the simulator). [edit] Support in various programming languages[edit] AdaAda is a strongly typed language where all pointers are typed and only safe type conversions are permitted. All pointers are by default initialized to [edit] BASICOriginally, BASIC did not support pointers. Newer dialects of BASIC, such as FreeBASIC or BlitzMax, have exhaustive pointer implementations, however. In FreeBASIC, maths on dim as integer f = 257 dim as any ptr g = @f dim as integer ptr i = g assert(*i = 257) assert( (g + 4) = (@f + 1) ) [edit] C and C++In C and C++ pointers are variables that store addresses and can be null. Each pointer has a type it points to, but one can freely cast between pointer types, although the behaviour is implementation-defined. A special pointer type called the “void pointer” allows pointing to any variable type, but is limited by the fact that it cannot be dereferenced directly. The address can be directly manipulated by casting a pointer to and from an integral type of sufficient size. While earlier standards did not have an integral type that was guaranteed to be large enough, C99 has added the C++ fully supports C pointers and C typecasting. It also supports a new group of typecasting operators to help catch some unintended dangerous casts at compile-time. The C++ standard library also provides Pointer arithmetic, that is, the ability to modify a pointer's target address with arithmetic operations (as well as magnitude comparisons), is restricted by the language standard to remain within the bounds of a single array object (or just after it), though many non-segmented architectures will allow for more lenient arithmetic. Adding or subtracting from a pointer moves it by a multiple of the size of the datatype it points to. For example, adding 1 to a pointer to 4-byte integer values will increment the pointer by 4. This has the effect of incrementing the pointer to point at the next element in a contiguous array of integers—which is often the intended result. Pointer arithmetic cannot be performed on Pointer arithmetic provides the programmer with a single way of dealing with different types: adding and subtracting the number of elements required instead of the actual offset in bytes. (though the While powerful, pointer arithmetic can be a source of computer bugs. It tends to confuse novice programmers, forcing them into different contexts: an expression can be an ordinary arithmetic one or a pointer arithmetic one, and sometimes it is easy to mistake one for the other. In response to this, many modern high level computer languages (for example Java) do not permit direct access to memory using addresses. Also, the safe C dialect Cyclone addresses many of the issues with pointers. See C programming language for more criticism. The int x = 4; void* q = &x; int* p = q; /* void* implicity converted to int*: valid C, but not C++ */ int i = *p; int j = *(int*)q; /* when dereferencing inline, there is no implicit conversion */ C++ does not allow the implicit conversion of int x = 4; void* q = &x; // int* p = q; This fails in C++: there is no implicit conversion from void* int* a = (int*)q; // C-style cast int* b = static_cast<int*>(q); // C++ cast In C++, there is no [edit] C#In the C# programming language, pointers are supported only under certain conditions: any block of code including pointers must be marked with the An exception to this is from using the // Get 16 bytes of memory from the process' unmanaged memory IntPtr pointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(16); // Do something with the allocated memory // Free the allocated memory System.Runtime.InteropServices.Marshal.FreeHGlobal(pointer); The .NET framework includes many classes and methods in the [edit] DThe D programming language is a derivative of C and C++ which fully supports C pointers and C typecasting. However D also offers numerous constructs such as foreach loops, out function parameters, reference types, and advanced array handling which replace pointers for most routine programming tasks. [edit] EiffelThe Eiffel object-oriented language supports pointers in the form of references, which are typed and do not allow any form of pointer arithmetic. The ECMA standard for Eiffel includes an "attached type" mechanism that claims to guarantee void safety. [edit] FortranFortran-90 introduced a strongly-typed pointer capability. Fortran pointers contain more than just a simple memory address. They also encapsulate the lower and upper bounds of array dimensions, strides (for example, to support arbitrary array sections), and other metadata. An association operator, type real_list_t real :: sample_data(100) type (real_list_t), pointer :: next => null () end type type (real_list_t), target :: my_real_list type (real_list_t), pointer :: real_list_temp real_list_temp => my_real_list do read (1,iostat=ioerr) real_list_temp%sample_data if (ioerr /= 0) exit allocate (real_list_temp%next) real_list_temp => real_list_temp%next end do Fortran-2003 adds support for procedure pointers. Also, as part of the C Interoperability feature, Fortran-2003 supports intrinsic functions for converting C-style pointers into Fortran pointers and back. [edit] Modula-2Pointers are implemented very much as in Pascal, as are [edit] OberonMuch as with Modula-2, pointers are available. There are still fewer ways to evade the type system and so Oberon and its variants are still safer with respect to pointers than Modula-2 or its variants. As with Modula-3, garbage collection is a part of the language specification. [edit] PascalPascal implements pointers in a straightforward, limited, and relatively safe way. It catches mistakes such as dereferencing a pointer into the wrong datatype; however, a pointer can be cast from one pointer type to another. Pointer arithmetic is unrestricted; adding or subtracting from a pointer moves it by that number of bytes in either direction, but using the Trying to dereference a null pointer, named [edit] See also
[edit] References
[edit] External links
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ↑ top of page ↑ | about thumbshots |