5

C is love, C is life.
Great language.

I genuinely don't get why so many people are struggling with pointers, considering it's a pretty straightforward concept. I understand that they can be complex in simplicity, but the concept itself is much easier to understand than say, references in OOP languages(despite being the same thing under the hood).

I mean it's just a number like any other number, except that number is treated as a memory address, and the star(* - dereference operator) just takes a value, goes to the memory address that is the value, and takes a value from there.
I feel like most explanations and tutorials just try to over complicate it for no reason.

Comments
  • 7
    I wrote a function in C that worked perfectly. But not if you executed a thousand times in a row. It concatted two strings and used reallocate. I know what happened, do you?

    Pony * pony = (Pony *)malloc(sizeof(pony)). Right, worked. Thousand lines later, code crashes on a random malloc while application worked perfectly.

    I love C too, but you do require experience. Reading one book doesn't make you a C dev. It's not python
  • 8
    The concept of pointers is simple, properly managing them isn't
  • 2
    @retoor the only two things that come to mind immediately is either the OS detected rapid memory growth, or wherever the app ran in ran out of memory, both triggering a null pointer on malloc. That's my suspicion, what was it actually?

    Also 100% agreed
  • 3
    @thebiochemic in my theory - later - I think realloc can have a null terminator in his data. strcat will overflow
  • 4
    @retoor fragmented heap and a large Pony?
  • 0
  • 6
    I think you are mixing up different things here. When people have problems with C, it’s not necessarily because they struggle to understand pointers.
    As @devRancid said, pointers are quite easy to understand unless you are an absolute beginner.

    The real problems with C is mostly the lack of automatic memory management and missing high level concepts like closures, classes for encapsulation of logic and polymorphism, generics, concurrency, etc.
  • 3
    Also, I feel like people who start with languages like Java, C#, JavaScript, etc. tend to struggle with pointers in C and C++ for obvious reasons.

    It’s hard to unlearn the wrong mental model of how memory works.
  • 2
    @retoor if the string concat by realloc stopped working after a few thousand times my first guess is forgetting to free?

    sizeof(Pony) instead of sizeof(pony) since sizeof(pony) is size of a pointer, which is just 8 bytes(usually), so it "works" because usually the memory right next to malloc'd memory is not used and not proteceted or anything, until one of the times the memory right next to the malloc'd one is protected or "not yours" or whatever and then accecing any field of Pony that is beyond the first 8 bytes would access that memory and SEGFAULT.

    And I don't really know python but I would assume reading a python book doesn't really make you a python expert either?
  • 2
    @Lensflare I'm not sure I agree(About people who start from higher languages)

    I started from Java and C#, and I didn't really struggle with comprehending pointers when I learned C. If anything, a lot of Java's OOP stuff suddenly became much clearer and simpler to understand after doing C for a while. In a "Ohhh, so this is how the magic works, it's simpler than it looks" kinda way.
  • 1
    @EqualityCoder python is very, very easy and therefor one of the best languages IMHO
  • 3
    Why people struggle?

    Say you allocate some heap for a structure of arrays, and some days later you realize there's a scenario in which you'd conditionally need to enlarge this block. You do so, and it works. And now it doesn't. Wait. What?

    Realloc may or may not move the buffer to a new location depending on whether there's sufficient adjacent space -- which means that all absolute pointers to the original block may or may not be invalidated.

    Storing offsets rather than the full address so that the base can be freely moved would fix the issue, but this is only immediately obvious if you have a solid grasp on memory.

    As to why do people seemingly have either poor understanding of fundamentals or no ability to apply that knowledge, I have not a single vitriol-free answer.

    In conclusion: skill issue.
  • 1
    @Lensflare I have seen people think free or delete sets the pointer to null...
  • 1
    @retoor isn't sizeof(pony) (Pony *) the size of the pointer itself. Where sizeof(Pony) would be the size of the structure?
  • 1
    I don't like programming in C. It feels backwards now.
  • 1
    @Demolishun yes - that's exactly what happened. The application even worked fine for a while. Crashed very random on a specific line nothing to do with it. But I ask you - how much time do you think it takes to figure this out?
  • 2
    @Liebranca Well... What you said about realloc is clearly defined in the documentation, and in every website that details the STL (Like cppreference for example), and in the K&R book... It is very CLEARLY documented how realloc works, and that what you described happens, so I see no reason why this should be a surprise or a "bug out of nowhere". If someone's code stopped working because of this it means they half-assed it or just copy-pasted from stack overflow... In which point I also expect there to be stuff like skipped failure checks and the code probably SEGFAULTs on every third incorrect sneeze.

    You don't even need to know memory(Tho I would greatly advise it when working in any low level context) you just gotta know how to read.

    Like it's not even an edge case, that's the normal behaviour.
  • 1
    @retoor dunno, it can appear anytime or never.
  • 2
    There are two related main reasons to find pointers difficult:

    1. the language errors, even compiler errors don't give beginners enough information and usually mention rules that don't suggest the behaviour that necessitates them

    2. the code doesn't give experts enough information and usually mentions low level details that don't suggest the high level structure that uses them.

    A pointer could be a borrow, an owned object that may or may not have live borrows and thus isn't generally safe to move or destroy, an owned or borrowed buffer, a nullable value the author felt too large to zero, an out parameter that may or may not be pre-initialized.

    ** has legitimate meanings for every combination of the above. If the exact parameters of both pointers aren't specified (and I've never seen them specified with sufficient rigor outside the standard itself) there's no point guessing because your chances are slim.
  • 2
    @EqualityCoder Yes. But the point is that if you already know what "reallocation" means, beyond the C implementation itself, then you would be expecting this behaviour to begin with; checking the documentation then is merely a matter of making sure your assumptions are correct.

    In essence, one should be able to reason about the code just by reading it, and that requires background knowledge that, apparently, very few people bother to acquire.

    I could be wrong, but that is my assessment.
  • 0
    @Liebranca the behaviour of realloc always felt common sense to me. This word doesn't really come up in other languages, except with vectors, but there it explicitly involves moving the elements.
  • 1
    @Liebranca I took one class in high school that walked us through pointers, algorithms, data structures, etc. After that it was a cake walk. I think this was in pascal. Moving to C/C++ was trivial. It has been so long I don't even remember Pascal syntax.
  • 2
    @lorentz Well, such things should be properly documented. At least I do so... For example if I write a function that returns a malloc'ed pointer I make sure to write that it's the user's responsibility to free the pointer, or if there's a structure that contains allocated pointers and there's a close/free/release function for it, I make sure to document it in the function that initializes the structure, and if I'm not sure how best to convey ownership/borrowing/responsility to the user in the docs I usually just open STL docs of some function that does something comparatively similar and look how they document it and take inspiration.

    I know writing docs and warnings and stuff like that can be hard, but that's something that just has to be done.
  • 0
    Pointers in and of themselves are simple, true. I bet people generally don't have much trouble with them fundamentally and conceptually.

    But you can do some truly wackadoodle shit with them, and that's where the problems begin.

    For example:

    int var = 789;

    int *ptr = &var;

    int **ptr_to_ptr = &ptr;

    printf("Value of var = %d\n", **ptr_to_ptr);

    ...or...

    int x = 10;

    int *p = &x;

    int **pp = &p;

    int ***ppp = &pp;

    printf("%d\n", ***ppp);

    ...or...

    unsigned long val = 0x1122334455667788;

    unsigned char *ptr = (unsigned char *)&val;

    *(unsigned int *)ptr = 0xAAAABBBB;

    printf("val = 0x%lx\n", val);

    I agree those are kind of convoluted examples, but the point(er) is that you definitely can write C code using pointers that is a real bitch to follow, and stuff ALONG THESE LINES isn't really super-unusual in large codebases because somewhere, someone at some time thinks "oh, this is clever!" and drops a nightmare in someone else's lap years later.
  • 1
    I hate c because it's too few letters. Rust? Now THAT'S a programming language. JavaScript? Oh god: perfect. Look at all those letters. Hypertext Markup Language? Clearly, that's the best of them all.
  • 0
  • 1
    Pointers are simple, but once you mix complex function pointer declarations into the whole spiel, things become hard to navigate.
Add Comment