DEV Community

Discussion on: Why use pointers at all.

Collapse
 
moopet profile image
Ben Sinclair

The simplest use case is passing things by reference.
Say you have a string like, "hello my name is Bob", and you want to make it all capitals?
It's fine to send that string over to a function in its entirety, wait for it to be tinkered with and copy it back.
But say you have something bigger, like an image, potentially a gigabyte in size, and you want to send it over to a function that finds the brightest colour in it? You don't want to be copying all that information across every time, so you use a pointer to tell the function, "here's my image, use it directly".

Pointers also allow you to do other stuff like links in linked lists or have variables of indeterminate size or even to directly change something on the display (what they call "memory mapping") and a few other tricks.

Collapse
 
jvarness profile image
Jake Varness

Pointers also allow you to keep references to multiple variables of the same type, kind of like an array, except with the help if malloc, calloc, and realloc you can point to as many variables of the same type as you want, provided the memory still has space to allocate.

Pointers enable you to have things like Strings in your C code (in the form of char*) since Strings aren’t native to C.

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

Let's check my loose understanding of char. char represents an integer type uint8 from 0 - 255 which is somehow synonymous with utf8 encoding. char* is somehow array like of chars by reference?

I think malloc does direct allocation of a value to memory? Not sure about the rest.

Thank you, This is fun!

Thread Thread
 
jvarness profile image
Jake Varness

You’re right on the money with chars, malloc doesn’t necessarily allocate a value, it allocates a segment of memory for that pointer based on how many bytes you tell it to allocate. This is why sizeof is an extremely important function to use when working with pointers, because it tells you how large any variable or struct is in bytes. If you wanted to make a pointer that was large enough to hold X amount of any type, you’d want to allocate X * sizeof(type) for that pointer, and you would want to advance it by sizeof(type) to get to the next thing it points to.

Pointers are what make me not like programming in C because it’s where a lot of very common problems can happen: segmentation faults happen a lot and the same code that might run fine on one OS might not behave the same on another.

Collapse
 
pentacular profile image
pentacular

I think it's important to note that passing a pointer by value is not pass by reference.

Passing the pointer by value grants the means to reference the thing pointed at on the other side, but it doesn't have pass-by-reference semantics.

e.g., this code can't change the value of p, so bar will always receive a null pointer value.

{
  int *p = 0;
  foo(p);
  bar(p);
}

If p were passed by reference then the value of p could be changed by the call to foo.

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

That makes sense, an image would be like 4 channels of uint8 so yes that's a lot of data. What happens if I pass the string "hello world" into a function not as a pointer, does the function create a copy in memory.

Collapse
 
jvarness profile image
Jake Varness

Hard-coded strings are considered to be of type const char* when compiled down, so the same rules that you would apply to anywhere that a char* is used. I can’t remember if const prevents you from reallocating the memory, or changing the address of the pointer. If I remember correctly, hard-coded strings are allocated in the heap, whereas other char* that are allocated at runtime are allocated on the stack.

I don’t think it creates a copy because pointers by their very nature are just memory addresses, but you can test this by examining the address as shown in this example: codingame.com/playgrounds/14589/ho...

Thread Thread
 
pentacular profile image
pentacular

Actually, they're not const char *.

A string literal produces a char array, so the type of "hello" is char[6], which evaluates to a value of type char *.

It is undefined behavior to mutate an object produced from a string literal, so it would be nice if the type system did help you out with a const, but backward compatibility ... :)

Note that there is no heap or stack in C. C has allocated, static, auto, and register storage instead.

Objects produced by modifying string literals can be allocated however the compiler likes, providing they have sufficient storage duration that nothing will ever notice them not being there anymore.

Because modifying them has undefined behavior they're often allocated in a read only part of the program's storage, like functions.

They may also be consolidated -- so you cannot expect "a" and "a" to produce distinct objects (but you also cannot rely on them not doing so).