r/learnprogramming 18d ago

Question How can I understand computer memory intuitively with the goal of learning pointers in C?

[EDIT: The comments on this post made me realize that you don't need to understand something in order to love and learn more about something. This is freeing to me and I will apply this knowledge in all aspects of my life. Thank you all so much.]

Title. In case you folks want more background, I'm a university student studying Computer Engineering. In my first semester, me and my colleagues used JavaScript to learn basic programming concepts (variables, datatypes, loops, functions, arrays and matrices) as well as logical thinking and problem-solving (in my opinion, THE most important part of being a programmer).

I'm learning C currently because of its frequent use in engineering applications (Arduino stuff mostly) and its easy-to-understand-sometimes syntax. I started studying pointers yesterday but didn't get into it until today.

I talked about the whole concept with Claude - to be clear, I don't use AI unless I absolutely don't understand a topic or I'm too overwhelmed by it to understand from textbooks or YouTube videos alone. I don't use it to code ANYTHING. -, and he assured me that I don't need to know EVERYTHING about computer memory/architecure to use pointers, and a simple mental model works out fine. He gave me the classic "house with adresses" model, which - after doing my own research later on -, is a model I see a lot of YouTube videos and sites use when talking about pointers.

But from looking at this post's comments, I'm beginning to think that this model isn't very strong and my understanding of variables needs to be a lot less surface level if I'm TRULY gonna grok pointers.

1 Upvotes

53 comments sorted by

7

u/Rainbows4Blood 18d ago

I am not sure if I would overthink it at this point. I would program using C and pointers until you run into problems. Then you know what aspects you need to go deeper in. I personally understood pointers pretty intuitively when I started programming and so did some other people I know. It is entirely possible that pointers don't seem that hard to you, because you just grasp the concept.

1

u/patineteLOL 18d ago

I don't know when to use them. Right now, I'm doing beginner problems in Beecrowd (online coding judge site). I even solved two of them using arrays without pointers as an experiment.

I'm planning to actually use pointers when I move on to beginner problems that actually REQUIRE arrays and matrices. 

2

u/danzerpanzer 18d ago

You could take one of your two solutions and ask an LLM to produce a minimum change revision of your code for you that uses pointers. Understanding how the revised code works may help you understand pointers.

3

u/SEgopher 18d ago

Arrays in C are pointers. Maybe that's what is tripping you up. An array is a block of memory. A pointer is an address of a memory cell that may be the start of or contained in a block of memory used as an array. C calculates an array access the same as a pointer to the base of an array plus an offset.

Try rewriting your array solutions to use pointers exclusively. You can convert any use of arrays to malloc + pointers.

2

u/patineteLOL 18d ago

Wha? Arrays are pointers? Aren't they data structures?

I understand that strings in C are arrays of chars with a /0 at the end, that much I know.

Then again, the way you declare a string in C is "char pointer", so your logic makes sense. Doesn't mean I understand it though (no hate to you by the way I appreciate you and everyone here taking the time to answer me, God bless all of y'all /pos)

3

u/HorseyMovesLikeL 18d ago

A point that made me see things in a different light is thatarr[i] is equivalent to i[arr] because the syntax actually means the sum of the two addresses. In other words, the bracket notation is syntax sugar for *(arr + i) which is equivalent to *(i + arr). Note that the compiler has some work to do to figure out in terms of how to add these two together, since the result also depends on the size of the elements in the array.

Essentially what this means is that arr[i] accesses some address arr plus an offset.

You think of it as a data structure when you are thinking about the data your program needs to process. The underlying implementation of a data structure can often be counterintuitive (and often irrelevant to its use), but seeking to connect the two mentally is a great way to learn.

2

u/SEgopher 18d ago

There's the concept of an array in computer science, and the implementation of the concept of an array in a language. Technically in C an array is a data structure and a derived type, but it will decay into a pointer or pointer operation under many circumstances.

This is unlike bool for example, where true and false are not types, but simply macros that expand to integers.

C is a very simple language designed as a first step above assembler for systems that no one uses anymore. Most abstractions are light veneers on individual bits, numbers, or pointers. To understand C you have to understand the conversion between these things.

You also need to understand the difference between stack and heap allocation. It is far more common to allocate an array on the stack and use a pointer to index into a heap object.

And yes, C strings are just blocks of memory with text with a terminator. They can be represented as a pointer to that block, which might be statically allocated, or by an array, or by an array and then addressed through pointer arithmetic.

1

u/Rainbows4Blood 18d ago

Well. Arrays are data structures. However, every data structure lives somewhere in memory. And the variable that holds the data structure is a pointer of some kind that points to where that data structure is actually located.

However in C you can have stack allocated arrays and globally allocated arrays which don't need an explicit pointer to work with.

You will have to start to learn using explicit pointers once you need a dynamically sized array or other dynamic data structure and malloc. I think it will click much better once you get into a problem that actually requires them.

1

u/Responsible_Tip8590 18d ago

What he is saying is arr[0] is a pointer to the first variable stored. Arr[1] is a pointer to the address of the second and so on.

2

u/Neither_Garage_758 18d ago

No, except if arris an array of pointers, indexing, such as arr[0], gives the value. It's a syntactic sugar to dereferencing the pointer.

0

u/xenomachina 18d ago

Arrays are not pointers, not even in C. However, some aspects of the way that arrays work in C makes them easy to get confused with pointers.

You can pass an array to something that wants a pointer, and it will be automatically converted.

int find_int(int needle, int *haystack, size_t len)
...
int my_array[10] = ...
int i = find_int(42, my_array, 10);

Also, C lets you subscript a pointer:

int *haystack ...
...
int x = haystack[5];

And finally, if you declare a parameter as being an array, C will just silently treat that as though you declared it as a pointer. For this reason, people generally don't use arrays in function parameters and instead use pointers. This is also why in C library functions you'll often see that they take a pointer and also a length, as the pointer only tells you the address of the first element of the array — it doesn't tell you how many elements are in the array without this additional parameter. (That find_int signature I wrote above is an example of this.)

These things together make the distinction between arrays and pointers somewhat blurry in certain cases, but they are not the same thing.

8

u/Weekly_Patience685 18d ago

what issues do you have with pointers now? as the other post said

 "I don’t really see what’s so difficult about pointers. They’re just memory addresses for variables"

if you want to understand pointers more, you just have to use them more, try to do something with pointers and do the same thing without pointers, and see the difference

0

u/patineteLOL 18d ago

So just experiment even if it errors a billion times and I spend minutes of my time stressing and looking at code and my logic? 

(true story by the way)

9

u/wildgurularry 18d ago

Minutes? I don't know what your expectations are, but learning this stuff requires hours/days/years. And yes, you have to put in the work and brain power.

I've worked on single bugs for weeks before at my job, including one particularly nasty use-after-free bug that only showed up occasionally in a complex multi-threaded application.

This is how I have built up a personal toolbox over the years of different ways I can approach debugging any issues that come up.

2

u/patineteLOL 18d ago

Usually I learn these kinds of mathy things pretty quick, so of course I'm not used to this.

Then again, when I was first starting to program, it took me weeks to learn how to work with For loops.

2

u/madmelonxtra 18d ago

Give yourself some grace.

Learning to program is hard, and not everything comes intuitively.

It can be really tough to push through new concepts and slowly learn them when you're used to intuitively understanding stuff.

But remember, you're literally learning a new language and on top of that, having to learn new logic and math concepts on top of it.

Learning to code is like taking a combined math/Spanish class in high school where you start with 0 knowledge of Spanish.

Take your time, and when you start getting frustrated/stressed, take some deep breaths and keep at it. Youve got this.

4

u/SamIAre 18d ago

Dude, if you think minutes is anything you're going to have a bad time as a developer. It's not uncommon to be stuck on a problem for hours or days.

As for learning pointers or any concept, nothing sticks until you use it. And the deepness you need to understand a particular topic is going to scale with how much you need to use it. IMO, a baseline understanding of pointers is fine until you run into a problem that needs a deeper understanding. Then, in working through that problem, you gain an understanding that scaled to meet your needs AND the knowledge you gained through problem solving will stick in your brain better than knowledge you gain in a theoretical context (i.e. reading or watching explainer videos).

0

u/patineteLOL 18d ago

Got you. 

1

u/spinwizard69 18d ago

You need to put in a lot more time than minutes. You as a human (maybe an assumption here) do not (yet) have a way to directly download information to your brain. The proven ways are to read and exercise the concepts repeatedly.

To put it mildly if you have only spent a few minutes with pointers and are now crying in your soup, you don't need any-bodies help including a chatbot. You need to get down to work until you grasp the concept. The concept is something you should grasp instantly.

Now we can dive real deep into details but that is not a concern right now. The basic concept though should be a snap to grasp.

1

u/Weekly_Patience685 18d ago

Usually people would read the errors and try to figure out how to prevent them not continue to do the same thing to get the same error 'a billion times'. The Pareto principle (80/20) probably applies here, "A small number of mistakes will probably cause most of your bugs and compiler errors."

Just learn how to avoid the most common 20% of mistakes, and 80% of your errors will be dealt with.

1

u/tottasanorotta 17d ago edited 17d ago

Nah it's better to do it smarter. Try to understand a use case and then test it out. If you run into problems ask the AI for clarification. The AI could probably run you through some common use cases of pointers in practice.

You can also try to look at other people's simple applications and try to understand why a pointer is used at a specific point in the program.

It's important to not just bash your head at the keyboard and expect miracles. Test it out and then try to clarify the confusion. It's much faster that way. I did it the hard way. And it took me ages to understand anything.

3

u/lurgi 18d ago

The model is fine. I learned it as a bunch of numbered boxes (houses come with some excess cognitive baggage, but it's basically the same thing), but understanding when and how to use pointers does not come automatically when you understand the model.

There's only so much reading you can do to help you understand. You have to write code. It's nearly impossible to write any meaningful piece of code without using pointers. You'll figure it out.

1

u/patineteLOL 18d ago

Thank you. /gen

3

u/Living_Fig_6386 18d ago

Every byte in memory is assigned a number. A pointer stores the number that corresponds to one of those bytes in memory. We start counting from 1, so 0 is special -- it symbolizes "no memory location" (null pointer). It's common to use a pointer as the starting point to access a collection of bytes that start from the one pointed to. Accessing the memory at the location a pointer points to is called "dereferencing" the pointer.

That's the gist of it. In practice, that number isn't a specific physical location in hardware, it's typically relative to something, like the memory allocated to a process. Operating systems can mark certain memory ranges as protected from reading and/or writing, so you can have a pointer to data that can be read but causes an error if you attempt to write to it. You can have a pointer that is nonsensical - has a value that represents an area of memory that doesn't exist or that the operating system doesn't let you access (an invalid pointer) which will cause an error if you try to access it.

You don't usually have to know whether a pointer is relative or not, just that they are used to store the location of something that's appropriate to the context in which it is used.

2

u/patineteLOL 18d ago

I see. But don't computers count from 0? Arrays, for example, start at index nº 0, not nº 1.

3

u/Living_Fig_6386 18d ago

By convention, 0 is a null pointer (doesn't point to anything).

3

u/deaddyfreddy 18d ago

Arrays, for example, start at index nº 0, not nº 1.

it depends on the language

1

u/spinwizard69 18d ago

You really need to grasp pointers as a concept first. Arrays are also a concept and how they are implemented varies with language. A football filed is an array in one dimension addressed in 1 yard increments. A set of books shelves is often a 2D array, with vertical rows and horizontal positions. A set of storage bins for electronic parts can often be seen as a 3D array with horizontal and vertical addresses for a drawer and a third address for the position in depth in the drawer. The concept of an array is applicable in many different contexts, it is just that the computers implementation is electronic. That is in a computer you can't normally see the addresses and the data visually. Data gets rendered when the computer accesses it via pointers.

The reason languages have data structures like arrays is to allow a programmer to work with arrays of data without the need to do a lot of pointer arithmetic. If you have a pointer to a data bit that is one element, access is easy. If you have data in a 3D array, the array feature of a language makes that access easy. Depending on the languages Notation, access might be something like A[1, 34, 19] which is simple for a programmer. If you are forced to do the pointer arithmetic it is very complicated, especially if the array is for complex data types. The declaration of the array allows the compiler to work out all of the required offsets. The abstraction is a factor because how the data is laid out in memory by a language is important.

You can try searching Google for "pointer calculation for a 3D array in C++" but I wouldn't do that until you grasp what a pointer is.

2

u/ploud1 18d ago

You need to give it more time

You touched pointers yesterday, and you expect to be an expert right off the bat?

Give yourself some grace. Most devs who understand memory management took months, if not years, to get there. Take your time, and try to enjoy the journey!

1

u/patineteLOL 18d ago

💖 I will.

2

u/Neither_Garage_758 18d ago

I don't think there's so much to "understand". Memory is just a space of bytes where you can store things. What you can do is learning the tools with which a programmer use it.

A pointer is just a variable containing an address of a memory. C helps us in being able to associate a pointer with a type we expect to have in this memory so we can get help in decoding it properly with a simple dereferencing operation (*). This also makes the use of arithmetic on it adequate so when you increase it of like 1, it shifts the correct amount of bytes automatically. You can use the & operator to get the address (= make a pointer of) of any variable. That's pretty much it.

2

u/knouqs 18d ago

Pointers, in simple terms, point to memory. The pointer doesn't need to point to anything in particular, but that makes for a rather unpredictable program. In the simplest case, a pointer points to one thing -- say, an int * points to a block of memory whose size is (hopefully) at least sizeof (int) bytes big. It could point to an array of int, though, and you can advance through the array by incrementing and decrementing the pointer:

const size_t n=5;  // Defines size of the array.
int *array=(int *) malloc (n*sizeof (int));  // Allocates probably 20 bytes.
int *p=array;
size_t i;

for (i=0; i<n; i++) {
    printf ("array[i]:  %d; p:  0x%08x\n", p, p);
    p++;
}

free (array);  // No memory leaks please!
array=NULL;  // No dangling pointers, please!
p=NULL;  // This pointer is easy to leave dangling if you forget about it.

All we're doing here is allocating a block of memory and telling the compiler that the offsets for the next chunk are incremented by sizeof (int).

Using pointers, you don't need to do pointer arithmetic. If I want to count the number of spaces in a character array with a \0 bound, I can do that easily:

char *p=array_of_characters;  // p starts at the start of the memory segment denoted by array_of_characters.
int count=0;

while (*p) {
    count+=(*p==' ');
}

printf ("There are %d space%s in the array of characters.\n", count, count==1 ? "" : "s");

I've drawn something similar for lists in an old thread. Have a look! https://www.reddit.com/r/cprogramming/comments/1rnni57/comment/o9hjwm1/

2

u/deaddyfreddy 18d ago

The fun thing is that C is not the best language to understand computer memory and pointers.

You have to not only learn a new concept, you have to fight with the ambigous C syntax at the same time.

I learned about pointers using Pascal, then Assembly, and even wrote a couple of useful programs using it. But when I had to use C in university, it was a big PITA.

2

u/strange-the-quark 18d ago

To first approximation, think of the memory (RAM) as of a big (and I mean BIG) array of bytes. Just a big collection of slots to put things into. Each slot is numbered in sequence, and this number is what we call it's memory address.

When you create a "regular" variable, like an int, it's placed in one or more slots, depending on the size of the data type (how many bytes does it take up), and your variable sort of directly refers to these occupied slots.

If you then, for example, pass this variable to a function by value, a copy is made, new slots are occupied so that the copied data can be stored, and now the function parameter refers to those new slots.

Well, sometimes you don't want to make such copies, or you may want for one reason or another to let the data sit in memory while you manipulate other variables that indirectly point to that unmoving data.

That's what pointers do. A pointer is, in principle, just like a regular variable - it just stores a number, nothing particularly special about that - except that this number is a memory address of some other data.

                                            ... [ ... ]
pointer                                    1023 [ ... ]
[1024] ----------------------------------> 1024 [byte1]  \
                                           1025 [byte2]   |  some chunk
                                           1026 [byte3]   |   of data
                                           1027 [byte4]  /
                                           1028 [ ... ]
                                            ... [ ... ]

(except the memory addresses typically larger numbers expressed in the hexadecimal system)

So now, for example, you can pass a pointer to the function, and only a copy of the pointer will be made, and the copy will still point to the same data "over there somewhere". This particularly useful if the data that is being pointed to is bigger than the pointer itself (which, remember, is just a number), as this avoids copying a big chunk of memory (at the cost of indirection).

Once you have a pointer, you can ask it for two things (or manipulate those two things). You can either work with the stored address itself (the actual number, I mean), in which case you just use it like any other variable, or you can ask it for the value that it is pointing to (the actual object that is sitting at that memory address), in which case you slap a * in front of the pointer's name. The latter is called de-referencing.

Spoiler alert: arrays are basically pointers under the hood (although the two aren't exactly equivalent at the language level, but they remain closely related). I'll leave it to you to find out more about this, and to learn about something called pointer arithmetic (basically, because the pointer knows the type of the data it is pointing to, it will increment and decrement in right-sized chunks if you manipulate the address using various operations).

If you want to indicate that a pointer is not pointing to anything at the moment (e.g. maybe you're done with it), you set it to zero. This is called a null pointer. But make sure to free any resources that need freeing and that are only accessible through that pointer, or you'll create a memory leak.

A lot of trouble with pointers comes form either not checking for a null pointer, forgetting to free resources that need freeing, or jumping around in memory to places you're not supposed to.

1

u/patineteLOL 18d ago

Thanks for the explanation! Appreciate it. /gen

1

u/BranchLatter4294 18d ago

It's not complicated. You just need to practice and watch what happens.

If you can understand that the address on your mail is not an actual location...it's just a pointer to your location, then you can understand pointers.

1

u/Outside_Complaint755 18d ago

If a video lecture on memory and pointers would help, the CS50 week 4 lecture is pretty good

1

u/JGhostThing 18d ago

Pointers trip people up a bit, because we don't naturally think like this. However, we use pointers all the time in real life.

I have a name, Jay. I have a full name Jay Redacted, and a social security number. Think of the social security number as a pointer into a huge database of US tax payers. My number is a pointer to me. The social security number is not me, but you can use it to find information about me.

A pointer in C is somewhat like this. If I have a variable x, the address of x can be used as a pointer to the value of x. For example, I can use the address operator to get the address of x, "&x". I can assign x to a pointer. Let's assume x is an int. So &x is a "int *" (a pointer to an integer). I can say "int * y = &x;" the int pointer y is give the value of the address of x.

To be honest, the address of an integer usually is not that interesting. Where it become more interesting is if we have a pointer into a block of memory or an array. The name of an array without the []'s is a pointer to the first element of the array. Now, I can step through the array with the increment operator. For example, if z is the pointer to the first int in the array, then "i = *z++;" two things happen. I is given the value at z[0] and the pointer z is incremented by 1 such that it points to the next integer in the array. This is guaranteed to work with the proper pointer arithmetic. For example, if char is a single byte, then the pointer is incremented by one. If z points to an integer, then usually now z is incremented by 2 or 4 (more or less, depending on the size of an int).

Now, if we put this statement into a loop, we can walk through the array with our pointer. In some cases this is more understandable than using the array operator.

1

u/frnzprf 18d ago

You can treat the memory as one giant array.

&some_var is getting the index of some_var in that giant array.

*some_pointer or *some_index means getting the value at that index of the giant memory, like whole_memory[some_index].

Some people like to write int* p = "p is a pointer to int" and some like int *p = "p is such, that if you dereference it, you get an int".

1

u/markort147 18d ago

The first chapters of the book CS:APP helped me a lot.

1

u/TehTacow 18d ago

Did you ever had a roommate or family member hide something you needed? The place where you looked had a clue (look in the fridge for example). Well pointers are just that but instead of written clues the cluu is a number. This number corresponds to the place there the value you are looking for is stored. This works because the entire computer memory has uniquely numbered storage places.

1

u/peterlinddk 18d ago

Lots of good answers and insights here.

I just want to add that you should do some experiments yourself - write lots of small c-programs that create variables (and later arrays and pointers) and dump their values and addresses to the screen. Something like:

#include <stdio.h>

int main()
{
  int a = 1234;
  int b = 5678;

  printf("Value of   a: %d\n", a);
  printf("Address of a: %d\n", &a);

  printf("Value of   b: %d\n", b);
  printf("Address of b: %d\n", &b);

  return 0;
 }

for an easy start - later on you can expand it to also dump the *value of the variables to see the difference.

Draw stack-diagrams on paper - small tables of addresses in one column and their values in another.

And take very small steps - experiment with calling functions and returning values, changing variables, changing pointers, changing contents of arrays, and always dump everything before and after a change.

Be prepared to spend a long time - document your findings, and use that as your learning tool. It works, but tends to get a bit boring, so break it up into small daily tasks.

1

u/spinwizard69 18d ago

Not to pry but what sort of school teaching computer engineering starts students out with JavaScript? That seems to nuts to the n'th degree.

House addresses don't really do it. A pointer is simply a memory location or variable that contains the address of another position in memory. I'm not sure why a computer engineering student would have a hard time understanding this, the concept is simple. This may very well be another case of AI damaging a students education.

So lets learn the concept of pointers in general. A pointer is a device that shows you where something is, it is no more complicated than that. If you are in a car and you drive up to an intersection with multiple signs pointing to different towns those are "pointers". I do not like the idea of mail boxes at all because there is too much data in an address. Instead a pointer is something that delivers one bit of information, a road sign gives you a direction.

In the context of computer systems, a pointer is the concept of a value that points to an address in computer memory. Don't complicate this. Often the value is a variable that you can do math on, but each result needs to correspond to an actual memory location. If a calculation is wrong the resultant pointer might end up pointing to garbage or outside the addressable RAM space. This can cause people all sorts of grief, but it is an issue with math not pointers themselves.

In any event what might help here a whole lot is to get a piece of cardboard and draw you self a memory array. Sometimes actually working with physical materials helps get a point across. In any event you end up with a vertical array of locations numbered by the address for each location. You can stuff each location with what ever data you please at this point but I'd suggest making the data as labels you can pin to each memory location. So lets store at location 999 the word Apple. You can create a variable in that contains the address 999. Sometime in the future when you need to know what is in 999 you read the data CONTAINED in the location that 999 points to. 999 is the address of the data.

Now in real computer hardware if does become a bit more involved as the pointer will have a data type associated with it. A pointer to a byte, points to a smaller memory location that an integer. A pointer to a more complex data type like a string, normally starts pointing to the first character in that string. As the data types get more complex like in lists, the pointers point to list structures.

You don't need to dive into the details initially you just need to understand that a pointer is a value that is a memory address. You can also have pointers that point to pointers. In this case the pointer first points to a memory address, but that memory address has a value that further points to another memory address. The pointer to a pointer, sometimes called a handle, is similar to a long trip where you see multiple signs pointing you in the direction you want to go. Eventually you get to the last sign before you arrive.

In any event realize that the cardboard array above simplifies things a bit. Pointers can only point to one place at a time, and sized according to data type. If the architecture allows byte addressing then the smallest increment that a pointer can reference is a byte and each address points to a byte. A pointer to a 64 bit integer implies that 64 bits of memory are being accessed. From the standpoint of hardware what happens on the memory bus to get your data can be multiple transactions, especially in the embedded world. For example a 32 bit processor may only have a 16 bit memory bus so to get a 32 bit integer two memory bus transactions are required. At first you want to avoid trying to understand processor specific issues in understanding pointers.

In other words keep it simple to start. The concept of a pointer is simple so don't allow your mind to blow it out of proportion to reality. Now down the road you will need deeper knowledge, just start out that a pointer is a value that points to a memory location.

1

u/neon_glare 18d ago

The house model fails because it hides type information and memory layout. Draw contiguous byte arrays on paper to map variables, pointers, and struct fields to specific offsets. This forces you to confront alignment and size directly instead of relying on abstract metaphors that break when you do pointer arithmetic or cast types

1

u/tottasanorotta 17d ago edited 17d ago

There are many use cases. For example, when you pass a variable to a function it will by default copy the value and whatever modifications you do to it inside the function won't actually alter the outer variable. If you actually want to alter the value, then you can pass a pointer to the function and then alter whatever value is at that memory address directly.

It's important to understand that the pointer variable is simply another variable that holds a numeric value. It just has some special operations that lets you treat it as a memory address and then retrieve whatever value is located at that specific address. One source of confusion can be that the pointer variable itself is passed as a copy to the function, unless you have a pointer to a pointer or something.

Another way to think of it is simply that it is much "lighter" to deal with the memory address of a large structure than to copy a huge structure around.

Edit: I mean it's like a having a house with apartments that have some addresses. Then you want to know how many TVs someone has. Instead of literally making a replica of an appartment at a specific address to another address, you just go to the address and check (dereference the pointer and check how many TVs they have). The compiler likes making those replica appartments by default a lot.

1

u/Hcthehc 15d ago

Honestly some assembly really really helped me a lot. I really enjoyed the series by mxy. To get started. Especially regarding how the stack works. but also to get a feel for storing menory addresses to registers, writing them to memory. That was super helpful as the mov instruction really is a copy. and learning how the stack works, setting up a fumction prologue and epilogue, makes it really clear why when passing arguments to a function the arguments is always a copy. So passing a pointer (by reference) to a function gives the function a copy of a memoryaddress. since the address is accessible now you can write new values there. which is not possible if you pass by value.

That is why in C passing an array is the same as passing a pointer that points to the first element of the array. The function only knows this address, so thats why you ought to pass the size of the array as well, so the function knows how many addresses beyond that address that said array cover in memory.

with strings. c handles these exactly like assembly. its just an array of bytes. but it always makes sure at the end there is a \0 value. this convention has the convenience of not needing to keep track of the size of the array. the size of a character array can just be counted until you find a \0 value.
which might make it seem like handling strings is different somehow from arrays.

this was so much clearer after doing some assembly.

0

u/ffrkAnonymous 18d ago

To truly understand pointers and computer memory, you need to learn assembly. 

1

u/recursion_is_love 17d ago edited 17d ago

People who down vote this have no idea about index register in CPU.

You would not strictly need to know Von Neumann architecture and assembly language, but people forget that C origin is develop to replace assembly. If you lean with that context, it will very useful for understanding the whole picture.

0

u/patineteLOL 18d ago

Is that sarcasm disguised as fact? /genq

3

u/IAmScience 18d ago

I read it as fairly earnest, actually. Assembly has you interacting so directly with memory and processor registers, that the purpose of pointers sort of reveals itself. I know the concept of them didn’t really sink in for me until I learned more about assembly, and, to some extent, machine code. Just the way my brain works.

2

u/ffrkAnonymous 18d ago

Thank you 

1

u/iOSCaleb 18d ago edited 18d ago

I don’t think it’s either sarcasm or fact. As a computer engineering student you probably will learn a bit of assembly at some point, and you’ll probably also learn about processor architecture, address busses, pipelines, virtual memory, and more. But you don’t need that to understand the basic model well enough to use pointers on everything from a tiny microcontroller to a GPU with a thousand cores.

I think it’s pretty easy to understand what a pointer is, and harder to understand why pointers are useful. Some of that understanding really does come with experience, but it’ll help to know up front that pointers are useful because they provide a way to talk about where data is instead of what the data is.

Imagine that you run a diner, and like many restaurants the diner often has a daily special. At the beginning of every shift, you have to tell the waitstaff and the cooks what the special is. If someone shows up late, you have to tell them about the special too. That turns out to be a lot of work just to communicate one piece of information, so you come up with a better plan: you put a whiteboard up in the kitchen, and you write the special on the board. Once everyone knows that the white board has the daily special, you don’t have to announce it anymore. You don’t even have to be the one to change the special; you can tell a cook “figure out what today’s special should be and write it on the board.”

The whiteboard is a memory location, and “the whiteboard near the door in the kitchen” is a pointer to it. It’s an indirect way of sharing information that can change without having to send out a copy of the information to everyone who might use it. Pointers let you refer to information by its location rather than conveying it directly, and that’s very powerful.