answersLogoWhite

0


Best Answer

The purpose of a pointer is to store a memory address and to allow indirect access to the value stored in that memory address. The act of indirectly accessing memory through a pointer is known as dereferencing. Thus a pointer is said to hold a reference; it "points" to the reference. However, a reference and a pointer are not the same thing. A reference is an alias, an alternate name by which we can refer to an existing object. An object can have many aliases, but aliases does not require any memory over and above that of the object itself, unlike a pointer which does require memory.


The address of a reference is always the address of the object being referred to (just as Bill and Billy are different ways of referencing someone with the name William). However the address of a pointer is always the address of the pointer itself; it is a variable just like any other. The value of a pointer is the address that is stored in the pointer; the address of the object being referenced by the pointer. The dereferenced value of the pointer is the value stored at that memory address; the value of the referenced object itself.


In C++, we can enumerate all the properties of a variable, a reference to that variable and a pointer to that variable like so:


int i = 42; // instantiate an integer with the value 42

std::cout<<"Address of integer: 0x"<<&i<

std::cout<<"Value of integer: "<

int& r = i; // refer to i

std::cout<<"Address of reference: 0x"<<&r<

std::cout<<"Value of reference: "<

int* p = &i; // point to i

std::cout<<"Address of pointer: 0x"<<&p<

std::cout<<"Value of pointer: 0x"<

std::cout<<"Dereferenced value of pointer: "<<*p<


The output of this code would be something like this:


Address of integer: 0x00FBFBAC

Value of integer: 42

Address of reference: 0x00FBFBAC

Value of reference: 42

Address of pointer: 0x00FBFB94

Value of pointer: 0x00FBFBAC

Dereferenced value of pointer: 42


The actual memory addresses may be different on your system. However, note that the address of the reference is the same as the address of the integer, the object being referenced. Thus r and i are aliases, different names that refer to the same object. As such they have the same value. After all, the are one and the same object. The address of the pointer, however, is a different address. This proves that pointers are variables like any other; they have an address all of their own. Note also that the value of the pointer is the address of i (and, by extension, the address of r). The third property, the dereferenced value, is unique to pointer types. This returns the value of the object that is referenced by the pointer value.


This is obviously a trivial example and doesn't cover the full range of a pointer's potential, however it's important to understand the difference between a pointer and a reference. Not all languages that support pointers also support references like C++ does, thus you will often see the terms pointer and reference being used interchangeably. C is a typical example because it has no concept of a dedicated reference types but it does have pointer types. To be crystal clear, a reference is the value stored in a pointer (the address being referred to), it is not the pointer itself.


Aside from the semantic difference, another difference between a pointer and a reference is that a reference must always refer to something whereas a pointer need not. When a pointer doesn't refer to anything in particular, it is assigned address zero. Memory address zero is a reserved address which cannot be dereferenced and a pointer that holds the value zero is said to be a null pointer. The importance of the null pointer will become clear.


Now that we have an understanding of what pointers can actually do, what are the advantages and disadvantages?


The main advantage is that we can use pointers to pass objects into functions by reference. Languages like C and C++ use pass by value semantics by default which means that when we pass an object to a function, the object is copied; only the value of the object is passed, not the object itself. If we want the function to operate upon the object itself, we must pass the object by reference, not by value. C has no concept of a reference, let alone pass by reference, but if we pass a pointer to the object, the pointer is passed by value, and since the value is a memory address, it is the same as passing the object itself, by reference.


This is both an advantage and a disadvantage. It is advantageous in that we can pass objects by reference, but it is disadvantageous because we must be certain the pointer is non-null before we can actually operate upon it. This means that every function that accepts a pointer as an argument will have to perform the exact same test upon that pointer; does the pointer actually point at something valid? In C++ we don't have this problem because we can simply uses a reference instead of a pointer argument. References can never be null; they must always refer to a valid object thus there's no need to test the reference.


However, sometimes we want to pass an object as an optional parameter rather than a required parameter, so passing a null pointer would be acceptable. We still have to perform the test for non-null, but there's no way to pass an object as an optional parameter other than by instantiating a default object which can be considerably less efficient than simply testing if a pointer is zero or not.


Another advantage of a pointer is that when we wish to allocate memory dynamically, we must keep track of the start address of the allocation. The operating system's memory manager knows exactly how much memory is allocated to each address, so when we're finished with a block of memory, all we really need is the start address and the memory manager takes care of the rest, making that block of memory available to any thread or process that requires it. However, sometimes the memory manager may report that there is insufficient memory to meet an allocation, so no memory can be allocated. That's not a problem because if an allocation cannot be met, the operating system returns address zero as the start address. so each time we make an allocation, we simply store the value returned by the allocator in a pointer. If it is null, there is no memory available. We cannot use references for this purpose because references cannot be null, thus a pointer is clearly advantageous here.


In languages that do not support pointers, such as Java, memory is allocated to the Java virtual machine (using internal pointers of course) and the JVM provides the memory management required by its programs. There's still the chance of running out of memory, but the onus of responsibility shifts to the JVM's memory manager, away from the programmer, which leads us to one of the biggest disadvantages of pointers.


If the programmer fails to keep track of memory allocations, the program will inevitably leak memory (known as a resource leak). That is, if he allows all pointers to a memory resource to fall from scope, there's no way to recover the start address and thus no way to release the memory to the system. The problem with pointers is that there is no concept of resource ownership. A pointer simply holds a memory address, but there's no way to determine if that pointer actually owns the memory it is pointing at or if it simply referring to memory that is shared. In truth, all memory is shared and no pointer can physically own the memory it points at. We can easily end up with hundreds of pointers to the same object. Therefore the programmer needs to take extra care to ensure that whenever memory is released back to the system, all pointers to that memory must be immediately nullified. This is easier said than done, because not all pointers may be in scope at the point the memory is released, thus they will still be pointing at what they believe is valid memory. Any attempt to dereference memory that has already been released will result in undefined behaviour because that memory may have already been reallocated so it may not even belong to our program let alone still be in a valid state. And if we attempt to release the same memory twice, undefined behaviour is the least of our worries. So it's important that the programmer be aware of memory ownership, even though there's no way to actually define that ownership with a pointer.


In C++ this is less of a problem because we can encapsulate resources in special classes known as resource handles. Technically, a resource handle is a smart pointer. It behaves exactly like an ordinary pointer would, except that when the smart pointer falls from scope it automatically releases its resource. Thus ownership of the resource falls to the resource handle itself. A resource handle can also pass ownership to another resource, thus ownership of a resource becomes more explicit. If we wish to share ownership, we can use specialised resources handles that deal with shared resources through reference counting. The count is increment each time we add a new handle to a resource and decremented each time we release a handle to that resource. When the count reaches zero, the resource is released when the one and only remaining handle falls from scope. We can also use weak references to shared memory. Weak references are more like ordinary pointers except they cannot release resources, but when a shared resource falls from scope, the weak references are automatically nullified. In languages that do not support resource handles, the onus is entirely upon the programmer to manage their own resources through "raw" pointers, which is a distinct disadvantage and is often less efficient because of the complexity of defining resource ownership in a system where ownership is not a native concept.


When used properly and in an organised manner, pointers have many advantages and can lead to more efficient code. For instance, being able to navigate your way through consecutive memory addresses is more efficient than navigating your way through a series of named variables. This is precisely how arrays work, even in languages that do not support native pointers. An array is simply a contiguous block of allocated memory divided into one or more elements of equal size. Knowing the start address of the allocation and the size of each element, we can refer to any one element in the array as an offset address from the start of the array. Of course most languages will provide a more convenient array index operator (technically a suffix operator) that allows use to access individual elements using a zero-based index value ([0], [1], [2], [3], etc). However, Behind the Scenes, we're actually doing pointer arithmetic. The 3rd element in an array can be found at index [2], but what this really means is that the element resides at the 2nd offset from the start of the array. Thus if an element is 4 bytes in length, the 3rd element will be found at the address that is 2 * 4 bytes from the start of the array. Simple pointer arithmetic like this is a constant time operation, thus we gain constant time random access to any element in the array, whether it is the first element, the last element, or any element in between.


Arrays are by far the most compact and efficient method of storing data elements of the same length and type. However arrays are not ideally suited to data that is variable length. This is because every time we add a new element to an array we must reallocate the array, which may mean copying the array to new memory. There are ways to minimise the need for reallocations, such as allocating more memory than is actually required, however this undermines the efficiency by allocating memory that might not be needed. Moreover, removing elements is problematic because we can only efficiently remove the last element in an array. In order to keep track of unused elements, the unused elements must reside at the end of the array so we only need to maintain a count of those elements, not where each one is. If we remove any other element besides the last, we must move all the elements that follow it in order to close the gap and move the gap into the unused block.


To maintain efficiency we can use other structures that do not require contiguous memory. For instance, rather than allocating a single contiguous block of memory we can divide the memory into separate blocks of equal size. Thus when we run out of space, we simply allocate a new block, leaving the original blocks in place; no need to reallocate them. This is achieved by creating an array of pointers, where each pointer refers to a separate block. We use additional memory to maintain this array, but we now have the advantage that an array can grow and shrink more efficiently without having to reallocate the existing blocks. In effect, we're actually creating an array of arrays, otherwise known as a multi-dimensional array. However, since the controlling array contains pointers and the value of a pointer is a memory address, we still have constant-time random access to any element, because when we refer to a pointer by its index within the pointer array, the return value is another array, thus we can use a two-dimensional suffix to access an individual element, just as if we'd allocated the array as a single contiguous block. This would not be possible without pointers.

Moreover, we can also more easily remove and insert elements from either end of the array, but not from the middle.


If we need to add or remove lots of elements in the middle of a structure, then we need a more complex structure known as a linked list. Each element in a linked list is a node and each node points to the next node. The last node, the tail node, simply points to null and we only need to keep track of the first node, known as the head node. We lose constant time random access as well as bidirectional access because, to locate any node, we must traverse the pointers from the head node. However, since the structure is now encapsulated by the nodes themselves, the nodes can physically reside anywhere in memory and we can insert and extract nodes simply by adjusting the internal pointers between the affected nodes. For instance, if we have nodes x, y and z where x points to y and y points to z, in order to remove y we first navigate our way from the head until we reach x (because it points to y, the node we wish to delete). We then copy the value of y's pointer (which holds the address of z). We can then release y from memory and finally replace x's pointer with the value we copied. So x now points to z.


With a linked list, all insertions must be done at the head because that's the only node we have constant time access to. However, if we point the tail back at the head instead of null we create a circular linked list. Since the tail now points at the head, if we keep track of the tail rather than the head then we get constant time access to both the head and the tail. Now we can insert at either end of the list in constant time. Although lists do not allow constant time access to any element in the lists, if we need to perform a lot of insertions in the middle of the list, it is more efficient than using an array because we only need to maintain the internal links of the affected nodes, we don't have to reallocate or move elements around in order to make room for insertions or cater for extractions. The pointers consume additional memory of course (one word per element) however it is more efficient overall. If we require bidirectional traversal, then we can add a second pointer to each node so that they point to the previous element as well as the next.


The concept of a bidirectional node can be extended so that rather than simply pointing forwards and backwards through a list, we can point left and right to construct binary trees, where every node has up to 2 child nodes. These are particularly useful when we wish to sort data. Each node represents the root of its own subtree such that the left node points to a subtree with values that are less than this node's value while the right node points to a subtree with values that are not less than this node's value. Thus when we insert values, we simply navigate from the root of the tree, traversing left or right according to the value in the current node until we reach a null pointer in the required direction. We then insert a new node at that position. If there is no root, the value simply becomes the root node. New nodes always have null child pointers.


Of course a binary tree can easily end up unbalanced such that there are more nodes on one side of the root than the other. To improve efficiency, we can adjust the internal pointers upon each insertion to maintain balance, making it more efficient to locate a value regardless of which side of the subtree it is situated. To enable this balancing, we need to insert sentinel nodes, which uses additional memory, but improves the overall efficiency of the structure. These trees are typically known as self-balancing trees or red/black trees.


All these non-contiguous structures (and more besides) share a common aspect in that they all use pointers to iterate through the sequence. In C++ we can take advantage of this and create an iterator class. This behaves much like a pointer would (and is not unlike a smart pointer in that respect), but we can overload the increment and decrement operators to make traversal of these structures more intuitive. Normally, when we increment a pointer, the value of a pointer is incremented or decremented by the number of bytes dictated by its type. But an iterator can be forced to replace its value with that of another pointer. Thus if we have an iterator to the start of a sequence and we increment that iterator, we automatically traverse to the next element in the sequence.


Pointers clearly have many advantages, but not all languages implement them. This is primarily because pointers are low-level and require a lot of knowledge and skill to use them properly and safely. High-level languages do implement pointers but they hide the low-level implementation details within objects including resource handles, smart pointers, iterators and so on. Thus complex structures like lists and binary trees are still possible in high level languages without using raw pointers but, behind the scenes, there's still a lot of raw pointer arithmetic going on, it's simply hidden from view and that much harder to reach them (if at all). But knowing what's going on behind the scenes inevitably leads to more efficient code and who knows...? It may even spark an interest in getting to grips with low-level coding. If you want speed and efficiency, pointers are the fundamental means of achieving it.

User Avatar

Wiki User

9y ago
This answer is:
User Avatar
More answers
User Avatar

Wiki User

11y ago

The main drawback is that they're a bit more difficult to use than references. References always point to valid data (they can never be NULL), but pointers may be NULL or may point to arbitrary data, including other pointers. The programmer is therefore entirely responsible for ensuring their pointers point at valid data before they can actually use that data; the compiler is not able to foretell the runtime condition of a pointer. When there is a choice between using a reference or a pointer to a reference, the reference is the preferred choice. But if there's any chance the reference could be NULL, a pointer must be used instead.

If memory is allocated to a pointer (using malloc or new), the programmer is responsible for releasing that memory, otherwise a memory leak will occur. By contrast, references will fall from scope automatically. However, a danger here is that the programmer may point to a reference that falls from scope, leaving a dangling pointer. Any attempt to access that pointer may result in a runtime error (if not, it is a "time-bomb" which may crash the program at a later time, with no indication as to the cause).

Pointers can also be used to "rove" within the data of an object, a structure or an array. While this is a powerful feature, great care must be taken to ensure the data is valid. For instance, overrunning a data buffer is a common source of errors and can lead to exploitation by hackers who may be able to inject arbitrary code into your code, with all the same privileges of the original code. This is particularly dangerous when functions accept pointers to unchecked data buffers which can overwrite the return address of the function to point at the "infected" code in the buffer.

While there are drawbacks to using pointers, with appropriate usage they make it possible to produce more efficient code than might otherwise be possible with references alone. Thus the only real drawback is when they are used inappropriately.

This answer is:
User Avatar

User Avatar

Wiki User

11y ago

Pointers are often misunderstood or mistreated by programmers, as they require a measure of care to ensure that they are used correctly. The most common causes of buffer overflows, general protection faults, and other program crashes or unexplained behavior can all be linked to the incorrect use of pointers. Freeing a pointer without setting it to null, for example, can result in a "dangling pointer", where it points to an area of memory that may have been allocated to a different memory structure. Miscalculating the size of a memory structure can cause data corruption or unusual program behavior. Therefore, pointers are often referred to as "dangerous", even though there is no harm in using pointers when they are used correctly.

This answer is:
User Avatar

User Avatar

Wiki User

14y ago

The main advantages of using pointers are

1.) Function cannot return more than one value. But when the same function can modify many pointer variables and function as if it is returning more than one variable.

2.) In the case of arrays, we can decide the size of th array at runtime by allocating the necessary space.

3.) In the case of pointers to classes, we can use polymorphism and virtual classes to change the behavior of pointers to various types of classes at runtime

Coming to the disadvantages of pointers

1.) If sufficient memory is not available during runtime for the storage of pointers, the program may crash (least possible)

2.) If the programmer is not careful and consistent with the use of pointers, the program may crash (very possible) A brief synopsis on the "rules" of pointers

1.) Always initialize a pointer by calling an allocator

2.) Alway check to see if the allocation request failed

3.) Always deallocate memory controlled by a pointer when done with it

4.) Never access memory that has not been allocated - pay attention to the size of arrays

5.) Never access memory that has been deallocated

6.) Do not allocate and deallocate memory with wild abandon, because that can fragment the virtual memory address space, causing future allocation requests to fail - particularly in long running programs such as web servers There are more advantages and disadvantages than these - these are but a few examples.

This answer is:
User Avatar

User Avatar

Wiki User

14y ago

There are no disadvantages of using pointers in C or C++. There are only poor programmers that write code that incorrectly uses pointers.

Its like anything else. You need to consider the meaning and use of a pointer, and only use it in its correct context and initialization.

It is true that pointers are a sensitive area, causing problems for many programmers, but the rules are the rules, and if you follow them you can write stable code using pointers.

  1. Never use a pointer without initializing it by a call to an allocator.
  2. Never use a pointer without checking to see if its initialization failed.
  3. Never use a pointer beyond the bounds of its allocation.
  4. Always deallocate a pointer after its use has ended.
  5. Never use a pointer after it has been deallocated.
This answer is:
User Avatar

User Avatar

Wiki User

12y ago

Pointers are particularly useful for memory operations.

Pointers can hold the address of a variable, the address of a structure, the address of allocated memory, any next and previous links in linked lists and so on.

Pointers are very useful (most C programmers use them as much as possible), but there are some dangers. There's the risk of writing data to the wrong addresses (pointer not correct initialised), reading data from the wrong addresses and so on. This could lead to data abort, lost data and many other problems. You absolutely need to be in control of any pointer you use.

How to use:

uint32_t *p_data; /* declare pointer of, type found in stdint.h */

p_data = (uint32_t *)malloc(100); /* allocate 100 bytes of memory */

/* p_data is now the pointer to the allocated memory */

This answer is:
User Avatar

User Avatar

Wiki User

7y ago

A pointer is a variable which can be used to store a memory address. This has many advantages, not least the fact that it is the only way to refer to anonymous objects. Not all languages support the notion of an anonymous object, but in C it is a fundamental aspect of the language. Consider the following:

int* foo (int count) { int* ptr = count > 0 ? malloc (sizeof(int) * count) : 0;

return ptr;

};

In the above example we allocate sufficient memory on the heap to store 'count' integers if count is greater than 0. The argument, count, is a named variable (a formal argument), so we can easily refer to it by its given name. But the objects allocated on the heap via malloc() are anonymous because those objects do not exist at compile time. If they did we could simply name them. However, we also have no way of knowing exactly how many objects there will be at runtime because count is variable. If we know how many objects we will need at compile time then we could name them but this would be impractical if we needed, say, 1 million integers; we cannot possibly name them all. Moreover, if there's insufficient memory to meet the allocation, there would may be no objects allocated at all and you cannot name an object that may or may not exist at runtime.

All objects in memory, including anonymous objects, have identity. That is, they have a unique memory address. Assuming there is sufficient memory to meet the allocation, all the anonymous objects will be allocated contiguously (one after the other). This means that if we know the identity of the allocation and the number and type of the anonymous objects, we can easily identify every anonymous object within the allocation. For this we need two variables, one to store the count of objects and another to store the identity of the allocation, a pointer variable.

In the above example we used a pointer to int variable (int*) named ptr. This one variable provides us with two of the three pieces of information we need: the identity and type of object stored in the allocation. What it does not provide is the count of objects and this highlights one of the problems associated with pointers; we have no way of knowing how many objects a pointer actually to refers to. All we can say with any certainty is that if a pointer stores a valid address then it points to at least one object. This highlights another problem. How can we be sure the address is valid? Consider the following:

int main (void) {

int count = 100;

int* ptr = foo (count);

// use objects...

free (ptr);

// ...

int x = *ptr; // error!

}

Here we allocated 100 integers on the heap, used them (in some way) and then released the allocation. However, the pointer (ptr) is still in scope and still holds the address of that allocation; it's pointing at memory that no longer belongs to us! That memory could be overwritten at any time by another process or even by another thread of our process. Any attempt to dereference memory that is no longer ours to dereference will result in undefined behaviour.

Most (and probably all) compilers will not pick up this error. A good compiler might notice we released the memory and then attempted to dereference that same memory, however the standard does not require this of a compiler. Most compilers will only warn against using uninitialised pointers.

Another disadvantage of pointers is that for every call to malloc() we must have a corresponding call to free(). In the above example, the allocation was actually made by the foo() function so it would be easy to forget that an allocation has actually taken place. In some cases allocations may occur within deeply-nested functions or the source code might not be available. At the very least we might expect the function to be documented somewhere:

// Allocate n integers on the heap and return a pointer to the allocation.

// Note: the caller is responsible for releasing the allocation.

int* foo(int n);

While this certainly provides us with the information we need, the compiler does not read comments and therefore cannot enforce the invariant. All responsibility for the allocation lies entirely with the programmer and that presumes the programmer not only reads the comment but fully understands the implications!

Despite these disadvantages pointers are a necessity in languages like C. Without them there would be no way to refer to anonymous objects.

You will note that the foo() function actually instantiates a variable-length array. The relationship between pointers and arrays cannot be underestimated. With fixed-length arrays we do gain a certain level of protection against misuse of pointers because the compiler provides a much higher-level of abstraction:

int main (void) {

int x[10];

assert (sizeof(x)==10);

x[0] = 42;

// ...

x[9] = 50;

}

Note that we don't need a separate variable to keep track of the length of a fixed-length array. Nor do we need to use pointer variables to refer to the anonymous variables within the array, we can use array suffix notation instead. However, this is merely sugar-coating. We can see this if we attempt to pass the array to a function:

int main (void) {

int x[10];

use (x);

// ...

}

It would be natural to assume we could simply declare the use() function as follows:

void use (int[10]);

However, this highlights one of many inconsistencies within the C language. Although we can certainly declare a function like this, it is dangerous to do so. Consider the following:

int main(void) {

int x[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

int y[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int z[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};

use (x); // ok

use (y); // ok, but almost certainly unintentional

use (z); // disaster: undefined behaviour

}

The compiler will happily compile this code even though y and z are clearly the wrong lengths expected of the function. We get away with passing y to the function for the simple reason that an array of length 11 is always guaranteed to have at least 10 elements. But an array of 9 elements clearly does not!

Let's consider how use() might be implemented:

void use (int a[10]) {

for (int i=0; i<10; ++i)

a[i] += 42;

}

You will note that the function makes no reference to the dimension whatsoever. The literal constant 10 used by the for loop is what we call a "magic number" and is completely independent of the 10 specified in the formal argument. Indeed, we can actually get rid of the 10 in the argument altogether and the function will still compile:

void use (int a[]) {

for (int i=0; i<10; ++i)

a[i] += 42;

}

Getting rid of the magic number is not quite so straightforward. It would be easy to assume we could simply use the sizeof() function to determine the runtime length of a (in bytes) and divide by sizeof(int) to get the number of elements. If we assume that sizeof(int) is 4 bytes in length (which is fairly common), then sizeof(a) would have to be 40 bytes for an array of 10 elements. However, it will undoubtedly come as a surprise to learn that sizeof(a) is anything but 40 bytes, it is more likely to be either 4 or 8 even if we include the dimension in the argument:

void use (int a[10]) {

for (int i=0; i

a[i] += 42;

}

At best this function might increment the first element, perhaps even the second. But it almost certainly won't increment all 10 and, in some cases, might not change any at all. The reason is simply that built-in arrays cannot be passed into functions by value even when the argument clearly specifies that they should. All arrays implicitly decay to a pointer variable and, as we saw earlier, a pointer cannot tell us how many elements it refers to. Even if we specify the count of elements, the compiler simply ignores it because there's no way to refer to the dimension other than through a magic number. And if we use a magic number, then the dimension is immaterial.

You might ask why the compiler even allows us to pass a dimension, however it is necessary when passing multi-dimensional arrays to functions. The first dimension will always decay to a pointer, but a multi-dimensional array is an array of arrays and we need to know the length of the "inner" arrays in order to interpret the pointer correctly. This implies that we must also pass the length of the outer dimension via a separate argument. And if we must do it for multi-dimensional arrays, we must also do it for one-dimensional arrays:

void use (int a[], int size) {

for (int i=0; i

a[i] += 42;

}

Given that the array implicitly decays to a pointer, the following is also valid:

void use (int* a, int size) {

for (int i=0; i

a[i] += 42;

}

Pointers are difficult to use at the best of times, but they become all the harder to use when we don't realise we are actually using them. However, once we understand the problems and learn to live with them, we quickly discover the advantages they have to offer.

Of course, high-level languages like Java don't use pointers at all. They still exist, of course, but the language does not allow us any direct access to them. Instead, we use resource handles or "smart" pointers as opposed to "naked" pointers. If we come to C after learning these languages then it can often be hard to see the advantages a pointer has to offer. It is probably easier to say that they are a necessity rather than an advantage.

Pointers also exist in C++, however the language is such that we very rarely need to use them. In the few cases where we do require them for "raw" memory allocations, we can easily hide the low-level implementation details within a class which takes care of the resource for us. In addition, C++ also provides a native reference type which is much easier to use and no less efficient than a pointer. Like an array it is merely sugar-coating, but the protection it offers is far more robust than that of an array; references don't implicitly decay to pointers.

This answer is:
User Avatar

User Avatar

Wiki User

16y ago

1.Dynamic memory allocation is possible with pointers. 2.passing arrays and structures to functions 3.passing addresses to functions. 4.creating data structures such as trees,linked lists etc

This answer is:
User Avatar

User Avatar

Wiki User

11y ago

Recursion is the biggest problem in function

This answer is:
User Avatar

User Avatar

Wiki User

13y ago

If you have shaky hands, a laser pointer can be very distracting.

This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: What are the various advantages and disadvantages of pointer in c?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Related questions

What is the Advantages and disadvantages of server side includes?

Server-side tracking is a method for collecting website user data on your web server rather than relying on the user's browser (client-side) for data collection. It has more advantages than disadvantages, which I have discussed in details below: Advantages of Server-Side Tracking Server-side tracking offers several benefits over traditional client-side tracking: Improved Data Accuracy and Completeness: Ad blockers, browser privacy settings, and unreliable internet connections can disrupt client-side tracking. Server-side tracking collects data on your server, ensuring a more reliable picture of user behavior even with these limitations. Enhanced Privacy Compliance: With growing privacy regulations, server-side tracking allows more control over collected data. You can potentially anonymize or aggregate data before sending it to analytics platforms, helping you comply with regulations like GDPR and CCPA. Faster Website Loading Speeds: Client-side tracking scripts can slow down websites. Server-side tracking offloads this work from the browser, potentially improving website performance and user experience, especially on slower connections. Richer Data for Better Insights: Server-side tracking allows you to combine website data with additional information stored on your server (user IDs, purchase history). This enriched data provides deeper customer insights for personalization, marketing optimization, and product recommendations. Better Attribution for Marketing Efforts: Accurate attribution of conversions (sales) to specific marketing campaigns is crucial. Server-side tracking captures complete user journeys across devices and touchpoints, leading to more reliable attribution data for your marketing efforts. Cross-Platform Tracking: Server-side tracking can capture data from various sources like mobile apps and websites, offering a unified view of user interactions across platforms. Greater Security: Sensitive user data may not be exposed directly in the browser, potentially improving website security. Disadvantages of Server-Side Tracking While beneficial, server-side tracking also has some drawbacks: Increased Complexity: Setting up and managing server-side tracking requires more technical expertise compared to client-side tracking. Potential Costs: Implementing server-side tracking may involve additional server resources or specialized software, leading to potential costs. Limited Control by Marketing Teams: Server-side tracking might require collaboration with developers for implementation and data access, potentially slowing down marketing teams reliant on quick data insights.


What are the advantages and disadvantages of using a DVD storage device?

c


What are the advantages of pointer?

Pointers in C are advantageous because they allow for referencing of data without actual manipulation of the data. It is also helpful because it is not necessary to recreate an instantiation of the data locally, but merely reference the pointer.


Advantages of pointer in c?

pointer in C have following advantages- 1.Pointer is a very useful concept for creating the important C data structures i.e. linked list, stack, queues and trees, which are very powerful in certain situations. 2.Pointers are very useful when we have to reflect more than one variable change in the calling function after call takes place i.e. though we can not return more than one value from a called function but we can always pass references (pointer variables) to the variables in calling function as parameters to the function.So all the manipulation using these pointer variables will be reflected in called funtion. 3.Pointer provides a lower level view of memory, it adds to our understanding of the things going on in your computer memory.


What is pointer to a member in objective c?

It is a pointer that points to a member of a structure.


How can you offset a pointer in C?

Increment or decrement the pointer by the required offset.


Pointer arithemetic in C?

no


What is the purpose of pointer in C?

the purpose of pointer in c for saving the memory space.,and reduce the length and complexity of the program


WHAT IS POINTER TO POINTER IN C POINTER?

Pointer in C is Memory Reference. It stores memory address of any variable, constant, function or something you later use in your programming. Pointer basically used to ease the referencing of variables and others or in polymorphism and inheritance.


What is stream pointer in c?

C does not have stream pointers.


What is Dazzling Pointer in c plus plus?

The pointer that points to a block of memory that does not exist is called a dazzling pointer or wild pointer


How do you declare a pointer variable in c?

int* pint; // instantiate a pointer to an int. float* pflt; // instantiate a pointer to a float.