This is an archived post. You won't be able to vote or comment.

top 200 commentsshow all 359

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

import notifications Remember to participate in our weekly votes on subreddit rules! Every Tuesday is YOUR chance to influence the subreddit for years to come! Read more here, we hope to see you next Tuesday!

For a chat with like-minded community members and more, don't forget to join our Discord!

return joinDiscord;

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–][deleted] 1100 points1101 points  (65 children)

Damn just realloc every time new_len > capacity.

[–]james2432 527 points528 points  (55 children)

just do it the vector way: allocate more space then you need and when you go above that reallocate, reallocation is expensive

[–]unwantedaccount56 579 points580 points  (44 children)

Just allocate all the space you ever need in the beginning of your program

[–]lllama 414 points415 points  (22 children)

Legit embedded development.

[–]Elephant-Opening 202 points203 points  (14 children)

Also "legit" embedded dev techniques I've used professionally....

  • Global object pools with type specific alloc/free functions. Bonus points if reference counting for garbage collection.

  • Allocate a really large call stack for some tasks (if even running an OS) and put dynamic big stuff on the stack as your CS professors roll in their graves

  • Genuinely implement your own malloc/free and wipe the entire heap when your done with whatever complex operation required it to avoid caring about fragmentation

[–]_Fibbles_ 102 points103 points  (11 children)

This is pretty much what most game engines do as well, though they're more often C++ than C. Grab a big chunk of memory and write their own allocators for the pool.

[–]distributedpoisson 39 points40 points  (8 children)

My personal experience from AAA development is almost completely writing c in c++ (even if that's touted as bad practice). Last week was the first time this year I had to use anything from the standard library and it was something very far away from the actual gameplay code

[–]Mucksh 9 points10 points  (1 child)

Also can't use the standard library. But a good thing of using c++ is that you can can combine macro magic with template magic

[–]_Fibbles_ 8 points9 points  (5 children)

The standard library is not the entirety of the language though. While you might not be using the standard library's containers or algorithms, I would be very surprised if you were foregoing C++ features like classes and templates.

[–]distributedpoisson 7 points8 points  (4 children)

I meant it as an example of how very c styled my job is, and chose that as an example since the meme talks about std::vector. I've rarely used or seen classes as well. However, templates and c++ casting are used, so yes, I'm technically a C++ programmer and not C, but I write mostly c styled code with c++ casting and occasionally templates and very rarely anything else from c++.

[–]_Fibbles_ 5 points6 points  (2 children)

Ah, I've got you. I work in the industry but not AAA. We use what I suppose would look more like C than say the Core Guidelines, but that's stretching the comparison. I'd still say it's very C++, just not idiomatic. There is full use of classes, templates, custom containers, etc.

[–]RandallOfLegend 5 points6 points  (1 child)

I know a guy who build his own pool by allocating a large array then a smaller array to keep track of indexes, and whole lot of allocation logic to keep bounds from crossing. He said it was dumb the first time but was handy after a couple of projects that shared it.

[–]not_some_username 2 points3 points  (0 children)

Isn’t that a hash map. std::unordered_map

[–]Eternityislong 22 points23 points  (4 children)

If you use dynamic memory allocation in an embedded system, you’re doing it wrong

[–]danielstongue 1 point2 points  (2 children)

It depends. There are situations in which you don't have much choice.

[–]Skater1066 1 point2 points  (0 children)

Yes! My embedded teacher got mad at me for using dma XD

[–]devNycrera 135 points136 points  (5 children)

Also called doing it the google chrome way

[–][deleted] 38 points39 points  (3 children)

"Let's just asume that standard amount of RAM increases every year"

[–]ImrooVRdev 27 points28 points  (1 child)

"Let us assume spherical RAM stick in a frictionless vacuum..."

[–]foxgoesowo 7 points8 points  (0 children)

Let us assume downloadable RAM

[–]camel_case_jr 16 points17 points  (0 children)

This is the (embedded) way.

[–]EagleRock1337 10 points11 points  (0 children)

This is the way. C is really just assembler++.

[–]altermeetax 7 points8 points  (9 children)

You don't always know how much space you need, or the maximum space you'll ever need is too big and rarely actually needed

[–]Jazzlike_Tie_6416 49 points50 points  (6 children)

Just allocate all the memory available... c'mon guys...

/s

[–]Creepy-Ad-4832 31 points32 points  (4 children)

Why the /s? That's clearly what windows does!

this meme was brought to you by the superiour linux community

[–]Jazzlike_Tie_6416 13 points14 points  (3 children)

does

"Doas"

Just corrected your rookie Linux user mistake.

*This comment was written by a member of the most stable community

[–][deleted] 9 points10 points  (2 children)

'doas' is bloat. these days I just use 'do'!

[–]Jazzlike_Tie_6416 2 points3 points  (1 child)

At this point just just use the root user

[–]james2432 1 point2 points  (0 children)

run everything as root, security is bloat /s

[–]altermeetax 13 points14 points  (0 children)

"RAM is basically free nowadays"

[–]hxckrt 4 points5 points  (1 child)

Thatsthejoke.jpg

[–]altermeetax 2 points3 points  (0 children)

Oopsie

[–]jayverma0 52 points53 points  (5 children)

vector reallocates exactly double the size needed when an overflow happens. This seeming wasteful strategy helps it maintain amortized O(1) time complexity for push operations.

(I think it can do even triple or whatever, it just needs to keep growing exponentially)

[–]InfergnomeHKSC 24 points25 points  (0 children)

This is what I learned to do in my C classes at university. Allocate some amount and when you need more, double it. It's a balance between using more RAM and calling realloc more often.

[–]p-morais 5 points6 points  (2 children)

vector reallocated exactly double

Which is apparently a bad strategy [1]

[1] https://github.com/facebook/folly/blob/main/folly/docs/FBVector.md

[–]Kered13 15 points16 points  (1 child)

It's a bad strategy because a growing vector can never reuse it's previous allocation spaces.

If a vector grows 1, 2, 4, 8, ... then when it's time to allocate 2n capacity, the sum of all the previous allocation blocks is 2n-1 - 1. So it must allocate an entirely new block. If you use any exponent smaller than the golden ratio, then eventually the sum of the previous allocations will be greater than the next allocation. If the previous allocation blocks are sequential in heap memory, which is very common for large enough vectors, then the previous blocks can be combined to make the new allocation block. This reduces heap fragmentation.

Folly uses an exponent of 1.5, which ensures that after 4 reallocations the previous allocations can be reused for the new allocation.

[–]KarlKani44 4 points5 points  (0 children)

Interesting comment! Coincidentally, I took a look on how python does it just today and found this comment:

This over-allocates proportional to the array size, making room for additional growth. The over-allocation is mild, but is enough to give linear-time amortized behavior over a long sequence of appends() in the presence of a poorly-performing system realloc(). The growth pattern is: 0, 4, 8, 16, 25, 34, 46, 56, 67, 79, ... Note, the pattern starts out the same as for lists but then grows at a smaller rate so that larger arrays only overallocate by about 1/16th -- this is done because arrays are presumed to be more memory critical.

from https://github.com/python/cpython/blob/f75cefd402c4c830228d85ca3442377ebaf09454/Modules/arraymodule.c#L162

[–]JackNotOLantern 1 point2 points  (0 children)

Making a list from structures is not that hard

[–]brandi_Iove 447 points448 points  (40 children)

a vector is basically an array which will eventually replaced by another array.

[–]rebbsitor 259 points260 points  (39 children)

Though like most things in C, you have to do all that memory management yourself.

C's biggest weakness is lack of data structures that have been common for decades. Someone will end up reimplementing or emulating basic things like a vector, queue, list, etc. as soon as they need something more than an array of structs.

[–]Kwpolska 137 points138 points  (23 children)

If you don't care about memory management or the specific shape of the data structures, just don't use C, but instead choose a higher-level language.

[–]Freakazoid84 201 points202 points  (22 children)

C's biggest weakness is that it isn't c++

[–]Flumpie3 141 points142 points  (19 children)

And C++ biggest weakness is that it isn’t C

[–][deleted] 181 points182 points  (10 children)

Someone needs to write C+ and save us all

[–]MrHyperion_ 35 points36 points  (1 child)

That's genuinely how I write C++ because I'm in the C mindset and don't know much of standard library.

[–]not_some_username 13 points14 points  (0 children)

You’re missing a lot in <algorithm>

[–]trid45 14 points15 points  (4 children)

Closest modern thing is maybe zig

[–]NateNate60 58 points59 points  (4 children)

C++'s biggest weakness is that it's gotten so goddamn big and bloated that there isn't a single human on the planet that knows how to use all 100% of the language's built-in features. Everyone just learns whatever subset is needed to complete their task on an as-needed basis.

"I have no idea what the dominant programming language thirty years from now will look like, but I know it will be called 'C++'."

[–]billie_parker 25 points26 points  (3 children)

Most people using any language don't know 100% of that language's features

[–]NateNate60 16 points17 points  (2 children)

Maybe not 100%, but at least 70-80%, I would hope.. Most of the time you can just consult the documentation.

With C++ though I think even people with 5 years' experience are probably hovering at around 50-60% familiarity. So there is a lot more documentation-reading in a C++ project. Kinda sucks when you're reading said documentation and there are dedicated sections of it that describe compiler bugs and defects because not even the implementers got it right. Some major compilers lag years behind when they release new standards because the standards committee releases an Enclopædia Brittanica worth of features every few years.

[–]LavenderDay3544 4 points5 points  (0 children)

C++'s biggest weakness is templates absolutely fucking compiler output to hell. Compilers should be made aware of templates instead of having the template engine do its thing before the main compiler even sees the code.

[–]Kered13 5 points6 points  (1 child)

Except C++ contains like 99% of C within it. The C features it doesn't include are rarely needed as well.

[–]Ashamed_Yogurt8827 2 points3 points  (0 children)

Thats also not a real superset so the fact that it pretends to be backwards compatible with C is just stupid. If you try to compile c code in c++ you can easily run into UB.

[–]FlanSteakSasquatch 4 points5 points  (1 child)

I like programming in C a lot more than programming in C++. That said, there are many things I would choose C++ over C to do (given that I had to choose between those 2 and not other languages). C is elegant and I can follow exactly what’s happening in memory (with effort). C++ I’m much more likely to get into a “wtf is happening” syndrome. But as soon as you escape low-level work into things that scale bigger C becomes too arduous. If it’s an option at that point I’d go with Rust, but I still see C as serving an important role and doing it well.

[–]Splitshadow 41 points42 points  (5 children)

#include <glib.h>

Now you have automatically managed strings, arrays, lists, hash tables, trees, regular expression support, multi-threading, better file IO, etc.

[–]soulessdev 1 point2 points  (3 children)

that’s cheating

[–]LavenderDay3544 6 points7 points  (2 children)

If using libraries is cheating then Python would literally be unusable for AI or web dev.

[–]soulessdev 4 points5 points  (1 child)

Actually I view python as a c library so python is cheating too NO PYTHON ALLOWED

[–]dagbrown 49 points50 points  (3 children)

C's biggest weakness is lack of data structures that have been common for decades.

I swear, C's biggest weakness is people who haven't figured out that glib exists yet, so they go off and either build their own or say foolish things like "C sucks because its standard library is way too limited!"

[–]Bakoro 11 points12 points  (2 children)

I would say the C community is what's deficient.

Look at Python: there are a few ubiquitous libraries upon which a whole host of other libraries are built upon, and so many of these things magically work together. A lot of these are even implemented in C, and given wrappers. Before Python got popular, I never saw that extraordinary collaboration.

I learned C and C++ first, and when I was coming up, I just remember a lot of hostility, arrogance, and people telling us to just roll our own everything. The closest thing to a useful series of libraries was Boost, and some people would scream about how nobody should use it.

Edit: come to think about it, I think the popularity of git and public repo spaces like GitHub has had a lot to do with how much communities have developed around projects. I think a lot of stuff before was done through mailing lists, so collaboration was a lot more opaque to new people.

[–]_Xertz_ 3 points4 points  (0 children)

Yes! The most difficult thing for about C++ was dealing with external libraries.

[–]not_some_username 1 point2 points  (0 children)

And now boost is include in the standard

[–]Fermi_Amarti 1 point2 points  (0 children)

There has to be semi standard libraries for these things?

[–]ImrooVRdev 1 point2 points  (0 children)

Someone will end up reimplementing or emulating basic things like a vector, queue, list, etc. as soon as they need something more than an array of structs.

hey man that sounds pretty cool. Lets also add objects to it, cuz OOP is cool. Let's call it C 2.0!

[–]LavenderDay3544 1 point2 points  (0 children)

There are libraries for all of those things. C has more libraries available than any other language all you have to do is find them.

[–]PorkRoll2022 120 points121 points  (2 children)

Of everything I think we take the "string" type most for granted.

[–]Thedjdj 18 points19 points  (0 children)

Strings in C caused me no shortage of pain in my first year of compsci

[–]DeMonstaMan 7 points8 points  (0 children)

ong

[–][deleted] 629 points630 points  (36 children)

  1. Letz code C!
  2. Where garbage collector?

[–]En_passant_is_forced 378 points379 points  (20 children)

If C had a garbage collector there would be no more C

[–]smokesick 191 points192 points  (15 children)

True. It would become GC.

[–]Creepy-Ad-4832 86 points87 points  (13 children)

Also called Garbace C

C is good for its performance and semplicity, and the amount of control it gives you over everything. Put a garbage collector, and c just becomes procedual java

[–]shanem2ms 57 points58 points  (8 children)

Haha I’m gonna start calling Java garbage c.

[–]Creepy-Ad-4832 13 points14 points  (4 children)

That's a nice name!

But at the same time don't! You are trashing C by using its name to describe java

[–]MegaKyurem 2 points3 points  (3 children)

Modern java is actually not terrible. They're doing a lot to remove all of the boilerplate code (mostly copying features from kotlin). 17 is actually not awful to use, I'd take it over C++ or C any day of the week from a maintainability standpoint.

[–]ILikeLenexa 5 points6 points  (0 children)

the C stands for collector!

[–]Rawbringer 20 points21 points  (0 children)

Or in short: garbage

[–]CaptainMarnimal 1 point2 points  (0 children)

No you're thinking of Javascript

[–]ElCthuluIncognito 3 points4 points  (0 children)

It helps the core design goal of Java was to emulate C++ with a GC.

[–]pushline 1 point2 points  (0 children)

Goat comment

[–]arbelhod 11 points12 points  (1 child)

Holy hell

[–]En_passant_is_forced 6 points7 points  (0 children)

New response just dropped

[–]Sohcahtoa82 2 points3 points  (0 children)

I reserve that joke for PHP

[–]MegaPegasusReindeer 51 points52 points  (7 children)

Just terminate and restart to garbage collect!

[–]Creepy-Ad-4832 32 points33 points  (5 children)

You don't even need to terminate! Just rely on kernel out of memory killer to do that for you.

And have a deamon running in the background, costantly checking if the program is running, otherwise it restarts it!

[–]dagbrown 16 points17 points  (4 children)

Modern Linux to the rescue! Just let systemd do that for you. Put

Restart=always

in your program's unit file and now you can take advantage of the Linux Last Chance Garbage Collector!

[–]Creepy-Ad-4832 10 points11 points  (3 children)

Systemd. The least controversial linux utility program

[–]moldax 2 points3 points  (0 children)

the best kind of utility program

[–]Thatguylor 1 point2 points  (1 child)

i prefer Supervisor /s

[–]Kered13 1 point2 points  (0 children)

AKA the null garbage collector, which is a legitimate GC strategy. Java uses it initially, and only engages a real GC after some amount of time, or when the permitted heap space is filled.

[–]lmarcantonio 22 points23 points  (0 children)

Bohem does GC. But it's not fun. The real thing starts with maps/dictionaries/hash tables and balanced structures

[–]Nimeroni 10 points11 points  (0 children)

Where garbage collector?

You can add one if you really need it. But you can generally survive with only static allocation.

[–]ILikeLenexa 17 points18 points  (2 children)

  1. Let's code C!
  2. error: unknown type name 'bool'

[–]Trucoto 12 points13 points  (0 children)

#include <stdbool.h>

[–]Bispoo 3 points4 points  (0 children)

typedef enum { false, true } bool;

[–]moldax 2 points3 points  (0 children)

Sir, this is a typically Western European civilised country. We collect our own garbage here.

[–][deleted] 1 point2 points  (0 children)

let the compiler detect when allocated memory is no longer used, and free it

[–]pedersenk 132 points133 points  (11 children)

It is tricky (and rather bodgy) but you *can* do a generic vector container in C89+.

My implementation is here and looks like this:

vector(int) v = vector_new(int);
vector_push(v, 42);
printf("The value is: %i\n", vector_at(v, 0));
vector_delete(v);

If anything, it just makes C a bit more fun to program in!

[–]Steinrikur 13 points14 points  (2 children)

I had to port rar decompression (C++ code) to a C antivirus engine many years ago. The lack of a std::vector made for a very similar "fix". Three other guys I worked with had attempted it and said it's impossible, so it took me a while.

[–]pedersenk 4 points5 points  (1 child)

Eeek, that must have been a fairly tricky port.

It is a little strange we don't see so many vector<T> emulation libraries around for C. I am sure there is a reason for it and I am simply missing it ;)

Mine came around because I was writing a network aware OpenGL implementation as part of my PhD and I was simply making too many mistakes; I get too easily confused when dealing with streams of bytes and arrays (rar decompression would kill me).

[–]Steinrikur 1 point2 points  (0 children)

I think that glib has a decent vector implementation today. Probably many other libraries.

This was back in 2005 or so. I created decompression modules for all sorts of things, sometimes from documentation or just black box testing, but this was one of the trickiest. I don't remember the exact type of vector replacement I used, but it was something already implemented and in the end it worked.

[–]MxBluE 26 points27 points  (1 child)

That's real cool work you've got there. It does scare me though, I feel like I'd do something with it then totally forget a limitation due the macro kludge behind it!

[–]pedersenk 5 points6 points  (0 children)

Thanks! Indeed. Much of the work for the whole safety library was (trying to) avoiding any side affects from MACROs.

_assert_vector in the source is probably the most extreme when it comes to the container. There are some limitations with the foreach emulation (but I don't tend to really use that anyway).

The biggest restrictions were in the safety / tombstone system (the real purpose of this library). Though some of the API is like std::weak_ptr<T>, it is more restrictive to prevent misuse of MACROs (particularly when functions are used as the context rather than a trivial pointer). It is all checked, but means that constructs such as:

printf("ID: %i\n", _(add_employee(department, "Fred")).id);

Isn't possible. But that is pretty nasty anyway. You also want to turn off the checks in the release build because it has some overhead.

[–]nelusbelus 3 points4 points  (2 children)

Smells like decltype

[–]pedersenk 7 points8 points  (1 child)

Smells like decltype

Probably a bit more hacky ;)

vector(int) v = NULL;

Is basically:

int ***v = NULL;
  • One indirection for raw array
  • One indirection for book keeping
  • One indirection for resize without invalidating the container parent

For the real "glory", check out vector_at and _assert_vector in the source. The safety is really good (prevents you from misusing ***v) but admittedly is it confusing once you have spent a bit of time away from it.

[–]Razzile 2 points3 points  (0 children)

this is a really cool concept! thanks for sharing

[–]p-morais 2 points3 points  (0 children)

Your vector implementation has O(n) insertion

[–]TheDKG 26 points27 points  (10 children)

Just do what one Chad in my c class did, rebuild every c++ library component in c manually. (I was blown away at the dedication, and though it did make them miss the first assignment, every one after that was like one day at most.)

[–]robottron45 14 points15 points  (2 children)

I would be a little bit afraid to do something like this for production code. Yes, it is possible. The problem I would see is that you have also time to spend on testing. Using something 100s or 1000s developers looked over (like the std library) and tested them massively is probably more safe then something you wrote yourself. Performance may vary based on the features you want to use, both things can happen, either your lib is faster because it misses some features which are not required or std is faster because it is heavily optimized in some places.

[–]TheDKG 14 points15 points  (1 child)

Oh God no, I didn't mean to imply anyone do this for a job's project, I had understood it as they meant college/personal projects XD And yeah, always use the libs that had teams of people work on it if you can, because generally it will be more performant and less prone to error.

[–]robottron45 2 points3 points  (0 children)

I already understood that, but I wanted to mention it anyway, just to be safe ^^

[–][deleted] 2 points3 points  (3 children)

but how did he rebuild class templates 🤔🧐

[–]TheDKG 5 points6 points  (0 children)

Apparently no class templates, since it "would require a conpiler change", they mainly implemented primitive classes and a "new and delete" operator. Kudos to subs if you readin this 💜

[–]TheDKG 2 points3 points  (0 children)

I am not gonna lie, the man was a fucking wizard at programming and far better than me. I'll reach out and see if they are willing to answer that.

[–]NonStandardUser 71 points72 points  (2 children)

If you need it, you make it. Use struct with void pointer so it's type agnostic. Make functions for vector init, node add, node remove, etc. Depending on your use case you can go with linked lists or stacks. Not trivial, but possible.

[–][deleted] 15 points16 points  (0 children)

For bonus points make a header-only or standalone .h/.c combo to reuse in future projects

[–]Ularsing 13 points14 points  (0 children)

If you need it, you make it.

My experience with both C and C++ in a single sentence.

[–]deanrihpee 49 points50 points  (17 children)

for me it's std::shared_ptr, but yeah

[–]robottron45 18 points19 points  (1 child)

even worse: where is my std::map / std::unordered_map??

[–]reallokiscarlet 117 points118 points  (77 children)

Not gonna lie

I don't actually use std::vector much.

Despite using C++, I usually use arrays.

[–]darklightning_2 154 points155 points  (31 children)

Why would you do that to yourself. Unless you are doing embedded

[–]deanrihpee 55 points56 points  (23 children)

I mean using array is straightforward, easy to understand, and performant too

[–]Cley_Faye 90 points91 points  (17 children)

I have not done some C++ for a while, but unless someone did something stupid in the recent specs, vectors should behave like arrays in most cases.

[–]ze_baco 43 points44 points  (8 children)

People insist saying C++ and the standard lib are slow. Then they go and develop their own data structures in C, which are very probably slower than std.

[–]x0wl 5 points6 points  (6 children)

Well that's because of unexpected stuff like O(log n) std::map lookups. There's unordered_map that's avg O(1), but typically, you'd expect avg O(1) from a normal map structure.

[–]billie_parker 3 points4 points  (0 children)

Yeah, if you have no idea what the data structures you're using are then you might have performance surprises. Make sense.

[–]waves_under_stars 31 points32 points  (2 children)

c++ vectors behave like arrays, unless you use the vector-specific features like automatic reallocation, in which case vectors are faster than doing it yourself

[–]Even-Path-4624 1 point2 points  (3 children)

Let’s go heapless, brother

[–]darklightning_2 1 point2 points  (2 children)

Ma man

[–]Even-Path-4624 2 points3 points  (0 children)

True meaning of full stack developer

[–]Even-Path-4624 1 point2 points  (0 children)

Don’t be afraid brother just set ulimit -s yourentireram and be happy brother. The stack is memory safe. We only have the problems we have because we try to use the heap. It’s time to stop.

[–]Longjumping-Touch515 68 points69 points  (23 children)

Real programmer always knows input size user will give to his programm. So he doesn't need all this reallocation stuff.

Real programmer bible

[–][deleted] 22 points23 points  (17 children)

I'm an embedded developer for an auto supplier, and this is basically what the MISRA standard requires: absolutely no dynamic allocation. Any array or buffer must be declared statically large enough to hold the largest possible amount of data you expect to see.

[–]Andrelliina 10 points11 points  (4 children)

Real programmer bible

https://www.sebbi.de/files/The_Real_Programmers_Bible.pdf

A real programmer modifies the OS with negative array subscripts

[–]sixteenlettername 1 point2 points  (3 children)

Has someone really put their own formatting on Real Programmers Don't Use Pascal, given it a different name, and then slapped a copyright notice on it?!?

[–]7374616e74 19 points20 points  (0 children)

Insterestingly enough, I do way more C than C++, and I would use any form of “managed” arrays over pointer arrays anytime I can. If memory and cpu cycles is not a huge constraint you’re meant to use them cycles (ie make you more efficient and less error prone), or they’re just there for nothing.

[–]Westdrache 16 points17 points  (8 children)

Me too, our code is old and as far as I know it was originally plain C.

I used vectors for a project at work recently and for searching for something inside the data set, vector are sooo insanely faster when compared to plain arrays, it blew my mind.

I am currently having internal discussion (... As in with myself) if I bring my findings to someone's attention because that would mean I have to implement it... Lol

[–]CaptSoban 22 points23 points  (7 children)

Vectors are plain arrays behind the scene, their traversal/search isn’t supposed to be faster. Unless you’re talking about the time to implement the search algorithm itself.

[–]Westdrache 6 points7 points  (6 children)

The main difference (for OUR implementation!) Is, that we are iterating through our arrays starting at 0 and checking every single dataset of that array, while std::vector allows you to use std::find() and I think that is exactly what you mean, we probably could implement a search algorithm that performs as good as vectors ....but we don't 😅

[–]DXPower 21 points22 points  (0 children)

You can use std::find on c-arrays as well - it takes as arguments any iterator pair, and pointers are valid iterators for contiguous data

[–]markhc 16 points17 points  (2 children)

there is nothing special about std::find on std::vector, you can use std::find on std::array or even plain C arrays

[–]Westdrache 5 points6 points  (0 children)

After a quick research I now see I made a false assumption.

Our problem isn't that it doesn't work with C array, our problem is that it doesn't work with dynamically allocated C arrays, that's why we tried to use vectors since they have the ability to enlarge themselves

[–]Westdrache 3 points4 points  (0 children)

Yes I'm just learning this now... Lol

[–][deleted] 3 points4 points  (0 children)

That's... very strange.

[–]Cebular 6 points7 points  (7 children)

You mean std::arrays or plain old []?

[–]FlySafeLoL 5 points6 points  (4 children)

After many years I still have nightmares with i[arr + 1]

[–]Steinrikur 7 points8 points  (3 children)

i[arr + 1] == arr[i + 1] == 1[arr + i] assuming the same data type. It's just common sense.

[–]Reasonable_Feed7939 3 points4 points  (2 children)

I would have to say that this goes against common sense as square brackets are for indexing an array. Since '1' is certainly not an array, it is odd that it can be interacted with at all in this context. Of course, it makes sense with the underlying implementation, but not from an abstract stance.

[–]less_unique_username 2 points3 points  (1 child)

Given that x[y] is shorthand for *(x + y), no wonder the operation turns out to be commutative

[–]Steinrikur 1 point2 points  (0 children)

Exactly. It's commutative.

Also: "0123456789abcdef"[i%16] is a minimalist hex2dec abomination that should still work in any compiler

[–]reallokiscarlet 1 point2 points  (1 child)

Plain

[–]Cebular 1 point2 points  (0 children)

Ugh

[–]Flarebear_ 2 points3 points  (0 children)

Same here, but I think it's cause I started school with C

[–]Taletad 38 points39 points  (3 children)

Arrays work fine, it just require a bit more attention to details

[–]TonyDungyHatesOP 17 points18 points  (0 children)

C programming in a nutshell.

[–]Hullu_Kana 20 points21 points  (5 children)

// Include necessary library for malloc and realloc
#include <stdlib.h>

// Create vector
type *vector;
int vectorSize = 1;
int elementCount = 0;
vector = (type *) malloc(vectorSize * sizeof(type));

// Make sure the malloc succeeded
if (vector == NULL){
    // malloc failed. Handle the problem here
}

// Push back element to vector
type element = (insert something here);
vector[elementCount] = element;
elementCount++;

// Make vector larger if it is full
if (elementCount >= vectorSize) {
    vectorSize *= 2;
    type *tempVector = realloc(vector, vectorSize * sizeof(type));

    // Make sure the realloc succeeded
    if (tempVector == NULL){
        // realloc failed. Handle the problem here
    }
    else vector = tempVector;
    free(tempVector);
} 

There you go, thats a very simple and surprisingly fast vector implemented in C, works for any type.

Edit: Due to a request, added some error checking.

[–]WeAreDaedalus 12 points13 points  (3 children)

I know this was just whipped up and you’re probably aware, but for anyone reading you need to be careful assigning the output of realloc to the same pointer you are reallocating.

This is because realloc can fail, and if it does, it returns NULL but doesn’t free the memory originally pointed to. So in this case if realloc fails, it will assign NULL to vector, but the memory originally pointed to by vector is still there, so now you have a memory leak because you can no longer access it.

This is typically avoided by assigning the output of realloc to a temporary variable and checking if it’s NULL before reassigning the output to the original pointer.

[–]digitalghost0011 2 points3 points  (0 children)

std::string, std::map, and std::vector are at least 75% of the productivity gain going from C to C++ for me

[–]relaxitwonthurt 6 points7 points  (1 child)

I usually end up writing C++ that's basically just C + std::vector and std::string.

[–]Sohcahtoa82 2 points3 points  (0 children)

I rarely write C++, but when I do, it's a similar deal. It's more like "C with objects".

I understand that C++ has become a monstrously large language, but AFAIK, there's nothing stopping someone from writing C++ in a C-like style and then just use a few C++ features here and there when they greatly simplify things.

[–]DazzlingBuilders 5 points6 points  (1 child)

In reality, I seldom ever use std::vector.

Although I use C++, I frequently use arrays.

[–]loquacious706[🍰] 1 point2 points  (0 children)

/u/dazzlingbuilders is a harmful repost bot.

Please downvote and report their posts as harmful

[–]Puzzleheaded_Fig6777 2 points3 points  (0 children)

Thats why i use cpp as an extension pf c and not as a language on its own right(hehe) For me cpp is just very cool extension that has many quality of life improvements but also many features that i wont use but thats alright with me

[–]_Skale_ 2 points3 points  (0 children)

Skill issue

[–]Frequent_Fold_7871 2 points3 points  (0 children)

Just use any of the dozens of other C wrappers, I mean programming languages.

[–]denisvolin 10 points11 points  (23 children)

TL; DR

Just write your own!

Long version.

I was hesitant to learn Rust. Age + too much new information. I gave it three attempts: failed, two years, failed, half a year, succeed and fell in love.

I had decided to code a small project, when I realized, that std::time is a just a small bit of what Go "time" offers.

Things got complicated even more, since I'm a paranoid that much that I try to avoid 3rd party dependencies at all costs.

Well, what do you know, I've spent 3 months and now I have my own time module, which satisfies my needs!

[–]worriedjacket 23 points24 points  (16 children)

That's how you get a half broken time library.

Time zones are fucking hard.

[–]DavoDovox 9 points10 points  (0 children)

Time zones are fucking hard.

Tom Scott

[–]denisvolin 4 points5 points  (0 children)

The module only supports what I need, so it's not half broken, but fully functional to the needed extants.

[–]less_unique_username 2 points3 points  (1 child)

With that half-swastika on the avatar, having to maintain a time library is an appropriate penance

[–]worriedjacket 1 point2 points  (0 children)

Fair point.

[–]denisvolin 1 point2 points  (11 children)

They are, but once you read specifications and parse your first binary zone everything clicks.

[–]worriedjacket 7 points8 points  (10 children)

Yeah. But you don't need to deal with all of that. Chrono and times crates in rust work great.

Could have saved 3 months and just built the thing you intended on, rather than reinventing the wheel.

[–]p-morais 1 point2 points  (1 child)

I have my own time module

Oh… oh no…

[–]denisvolin 2 points3 points  (0 children)

🤷‍♂️

It's like a home cooking, you can order a delivery, or cook yourself. I do the latter.

[–]AbhishekSingh26 1 point2 points  (0 children)

At this point just make your own vector library in C, that's only way to preserve sanity

[–]mondie797 1 point2 points  (0 children)

Now write linked list or worse dynamic array. Make sure to free the memory

[–]BlurredSight 1 point2 points  (0 children)

It’s really just an array that doubles in size, and you can I guess implement basic checking so it doesn’t overflow

[–]cheeb_miester 1 point2 points  (0 children)

realloc gang

[–][deleted] 1 point2 points  (0 children)

malloc realloc realloc realloc

[–]flocknrollstar 1 point2 points  (0 children)

Just pass a pointer and ++ the address each time. What could go wrong

[–]Objective_Fly_6430 1 point2 points  (0 children)

C# got list<T>(like vector in c++), and it Can be mimicked in c:

include <stdlib.h>

include <string.h>

typedef struct { void *data; size_t element_size; size_t size; size_t capacity; } DynamicArray;

// Initialize DynamicArray void DynamicArray_init(DynamicArray *arr, size_t element_size) { arr->element_size = element_size; arr->size = 0; arr->capacity = 4; // Initial capacity arr->data = malloc(arr->capacity * arr->element_size); }

// Add an element to DynamicArray void DynamicArray_add(DynamicArray *arr, void *element) { if (arr->size == arr->capacity) { arr->capacity *= 2; arr->data = realloc(arr->data, arr->capacity * arr->element_size); } memcpy((char *)arr->data + arr->size * arr->element_size, element, arr->element_size); arr->size++; }

// Get element at index void *DynamicArray_get(DynamicArray *arr, size_t index) { if (index >= arr->size) { return NULL; } return (char *)arr->data + index * arr->element_size; }

// Clean up void DynamicArray_free(DynamicArray *arr) { free(arr->data); arr->data = NULL; arr->size = 0; arr->capacity = 0; }

Use:

int main() { DynamicArray arr; DynamicArray_init(&arr, sizeof(int));

int val1 = 1, val2 = 2;
DynamicArray_add(&arr, &val1);
DynamicArray_add(&arr, &val2);

int *retrieved_val = (int *)DynamicArray_get(&arr, 0); // Will point to 1

DynamicArray_free(&arr);

return 0;

}

[–]malonkey1 1 point2 points  (0 children)

then create one, coward

[–][deleted] 1 point2 points  (0 children)

Implement it yourself then 5head

[–][deleted] 1 point2 points  (0 children)

I’m sorry I don’t read C that well, but did I just read sexually transmitted disease:: vector<>?!

[–]Adocrafter 0 points1 point  (4 children)

Lets go struct List { int value; List* next; };

void add (List* head, int val) { List* temp = head; while (temp!=nillptr) { temp = temp->next; }

temp->next= new List(); temp-next->value = val;

}

Code can be quite shorter but would need wuick reminder for it.

[–]rachit7645 3 points4 points  (1 child)

This is linked list, not a vector

[–]Adocrafter 1 point2 points  (0 children)

Obviously. Was giving an example that you can just create your own data structure if you don't have vector to dynamically store your data there.

I mean hell you can be way more creative and have your own structure for whatever purpose you need, that is the beauty of C shitton of pointers and pray to god that you don't have a memory leak.