#development

1 messages · Page 173 of 1

sharp geyser
#

maybe it just hates me

civic scroll
radiant kraken
#

tbh

#

C++ hates everyone

sharp geyser
#
cmake_minimum_required(VERSION 3.26)
project(Vector)

set(CMAKE_CXX_STANDARD 20)

add_executable(Vector main.cpp
        Vector.cpp
        Vector.h)
#

even the cmake says its c++20

civic scroll
#

no i mean the cxx standard in the ide settings

sharp geyser
#

Im pretty sure I set it to above c++ 17

civic scroll
#

sometimes it choses to not include certain headers if language standard is set to older ones

sharp geyser
#

where is it at in clion

civic scroll
#

settings -> build / exec / deploy iirc

#

or just type c++ at the search bar

#

look for anything mentions language level

earnest phoenix
#

Try running clang++ -std=c++20 -O3 Vector.cpp main.cpp in the command-line and see if that works

civic scroll
#

waiting for clang#

sharp geyser
#
PS C:\Dev\Vector> clang++ -std=c++20 -O3 Vector.cpp main.cpp
In file included from main.cpp:2:
./Vector.h:19:32: error: no template named 'optional' in namespace 'std'
   19 |         int* insert(int element, std::optional<int> index);
      |                                  ~~~~~^
1 error generated.
earnest phoenix
#

Hmm... are you sure you've saved the file after including the appropriate header?

radiant kraken
sharp geyser
#

Clion auto saves

#

so I am sure

civic scroll
#

jokes aside, my dad does .net dev and he asks me with his stuffs sometimes

radiant kraken
#

damn

earnest phoenix
radiant kraken
#

do u use c#

civic scroll
#

i do

#

when i help dad

radiant kraken
#

thats nice

sharp geyser
#

which is why I am even more confused

earnest phoenix
sharp geyser
#

even main.cpp doesn't have 19 lines

civic scroll
sharp geyser
radiant kraken
#

just use notepad like me topggSunglasses

#

imagine using an ide

sharp geyser
#

even c++ dont want me to succeed

civic scroll
#

did you change language level in settings

sharp geyser
#

cant even find that option

#

so no

civic scroll
#

damn

#

time to turn on my laptop

sharp geyser
#

there isn't even an option

#

the only thing you can do is set it via cmake

radiant kraken
#

@sharp geyser maybe its time for u to go to bed mmLol

earnest phoenix
#

The error occurs in your header file, not source file

#

Show that

sharp geyser
#

do you need to do #include <optional> in header files?

earnest phoenix
#

Yes

sharp geyser
earnest phoenix
sharp geyser
#

No one told me this

#

😭

#

Well now its giving issues

#

saying that insert expects 2 arguments

#

I thought to whole point of using std::optional was to let it know that it isn't required

radiant kraken
#

well

#

the error explains for itself

sharp geyser
#

but like

#

it shouldn't expect 2

#

it should expect 1 with an optional param

#

no?

earnest phoenix
#

Show the error

civic scroll
#

oh

#

what

radiant kraken
#

lmao

civic scroll
#

you imported the lib?

radiant kraken
#

now turn off ur laptop

civic scroll
#

oh that's good

#

no

#

time to implement vector

sharp geyser
#
C:/Dev/Vector/main.cpp:9:16: error: too few arguments to function call, expected 2, have 1
    9 |         vec.insert(100);
      |         ~~~~~~~~~~    ^
C:/Dev/Vector/Vector.h:20:7: note: 'insert' declared here
   20 |         int* insert(int element, std::optional<int> index);
      |              ^      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
radiant kraken
#

bru

#

u forgot a second argument

#

u need sleep man

sharp geyser
#

but isn't the whole point of using std::optional to define it as an optional argument?

radiant kraken
#

std::optional does not behave like JavaScript's definition of "optional"

sharp geyser
#

okay

#

so how do I do something similar

earnest phoenix
sharp geyser
#

cause I don't always want to have to supply index unless I am wanting to set a specific index

radiant kraken
#

though i recommend doing something like this @sharp geyser

#

its much cleaner than using std::optional for the second argument

earnest phoenix
#

Not really because it duplicates implementation

radiant kraken
#

wait really?

#

how

earnest phoenix
#

Doing that requires you to provide the function body multiple times

radiant kraken
#

but its much cleaner to the user, no?

#

idk, this is just personal preference

sharp geyser
#

yea I dont understannd nullopt from that reference thing so ima just say fuck it and just supply an index

civic scroll
#

right?

radiant kraken
#

wait is that really allowed

#

dont u have to use std::nullopt or something

earnest phoenix
# radiant kraken but its much cleaner to the user, no?
int foo(int bar) {
  // Some 50 lines of code
}

int foo(int bar, int baz) {
  // Same 50 lines of code with adjustments to use `baz`
}

// Meanwhile

int foo(int bar) {
  foo(bar, std::nullopt);
}

int foo(int bar, std::optional<int> baz) {
  // 50 lines of code, adjusting based on value existence (`std::optional::has_value()`)
}
sharp geyser
#

at least according to my tests

#

dk if that expected behavior

sharp geyser
#

Also is there a need to differentiate between length and capacity?

earnest phoenix
sharp geyser
#

could I not just use capacity to determine my length?

radiant kraken
#

ahhh icic

#

so its like a memset(&thing, 0, sizeof(thing));

#

but at compile-time

earnest phoenix
#

Yes

radiant kraken
#

very pog

#

good job C++

earnest phoenix
radiant kraken
#

you cant

#

there's a difference between the array's capacity in memory and the amount of populated elements (length)

#

the array's capacity after initialization is always > 0, while its length can be zero

sharp geyser
#

uh oh spaghettio

earnest phoenix
#

Capacity is just a integer telling you when to extend the internal array when the length reaches the capacity

The reason you need to declare a length field/property yourself is because you're using a pointer to store the values which does not have size information as I showed before

sharp geyser
#

So wait

#

but capcity seems to always be equal to length in my implementation

#

which was why I was wondering

#

seemed like a wasted variable

earnest phoenix
#

Can you show your current implementation?

civic scroll
#

i'm thinking like this

sharp geyser
civic scroll
#

for my impl, the capacity doubles the size of size

sharp geyser
#

I wasn't sure if I should double it

civic scroll
#

up to you

#

you can always trim if you want

sharp geyser
#

or just add +1 for each element that is added

civic scroll
#

though

sharp geyser
#

so it is always equal to the amount of items in the vector

civic scroll
#

you will need to allocate a new array everytime an element exceeds capacity

#

since array is constant-size

sharp geyser
#

also what is auto

civic scroll
#

"infer the type from this expression"

earnest phoenix
sharp geyser
#

right

radiant kraken
#

its cleaner than new, then delete

earnest phoenix
#

The capacity should start from 1, and be increased by power of 2 every time the length reaches the capacity

radiant kraken
#

or does that also not work? notlikekomi

civic scroll
#

uhh guys

#

i uh

#

love can you stop the leak

radiant kraken
civic scroll
#

oh dtor

#

mb

lyric mountain
#

so basically a towers of hanoi but without moving pieces around

eternal osprey
#

yuhh

#

i just redid my algo to have a better complexity i can send you the code

lyric mountain
#

it's simple then, just sort the values descending

eternal osprey
#

irght now it is almost correct almost.

civic scroll
#

wait uhhh what happens if i free a pointer

#

does it know how much to free

eternal osprey
#

Instead of 6 it returns me 5 for one test case..

lyric mountain
#

they have no value by themselves

eternal osprey
#

But still i have no clue what's wrong with my algo. Something small is off.

radiant kraken
earnest phoenix
civic scroll
sharp geyser
#

wtf is T

civic scroll
#

inner type

#

i use generics

earnest phoenix
#

The type your vector holds

radiant kraken
#

if you free a pointer it should the same pointer (not modified with pointer arithmetic) as the one you initialized with new/malloc

sharp geyser
#

I don't even know how to use generics yet

civic scroll
sharp geyser
#

so for now ima stick with ints

radiant kraken
lyric mountain
sharp geyser
#

@earnest phoenix But I have a question, if length starts at 0, and capacity starts at 1, how is insert ever supposed to work.

lyric mountain
#

as you already know that if i is smaller, i + N will be smaller too

sharp geyser
#

It would never evaluate to true

civic scroll
#

oooooh much cleaner

#

thanks volt and nil

sharp geyser
# radiant kraken THIS

Yes but like, how am I to ever increase the length if I can't insert anything into the vector

#

😭

#

so length == capacity will always be false

radiant kraken
#

you can?

radiant kraken
#

length will always be less than capacity

civic scroll
radiant kraken
#

yes

sharp geyser
#

😔

eternal osprey
sharp geyser
#

I guess I am not making myself clear enough

radiant kraken
#

if you initialize it with new thing[69];

#

otherwise delete thing;

lyric mountain
earnest phoenix
sharp geyser
#

So length starts out at 0, capacity at 1. insert is my method for adding things to the vector. Vector is initalized with nothing in it. So how do I add stuff to it, if its length is 0, but its capacity is 1

#

length == capacity will always be false in this case

civic scroll
earnest phoenix
#

delete value[] is a syntax error

civic scroll
#

wait how come my ide doesn't tell me anything

earnest phoenix
civic scroll
#

something like

sharp geyser
#

oh wait

#

I see that now

earnest phoenix
#
void push(...) {
  if (current == capacity) {
    // Capacity reached, allocate new array with higher capacity and move elements of the previously allocated array to the new one
  }

  // Add element
}
eternal osprey
radiant kraken
sharp geyser
#

bro sorry

#

😭

lyric mountain
#

why are yall using vector btw?

sharp geyser
#

no reason really

#

just implementing my own vector

lyric mountain
#

oh no, I mean chitty

sharp geyser
#

oh

eternal osprey
#

i have sent the test logs in your dm as well

lyric mountain
#

I saw it

#

for dynamic arrays u use List not Vector

#

that's why I was confused

eternal osprey
#

owh yeah my teacher told me to use vectors tho

lyric mountain
#

weird

sharp geyser
#
100
-33686019
100
1000

Okay I am doing something funky here

eternal osprey
#

I am 100% sure that my first part of createboxpartitions is correct

civic scroll
#

@earnest phoenix also how can i infer the length of this kind of constructor?

auto a = Vec<int>{1, 2, 3};
eternal osprey
#

because it outputs 6

#

however, in the second part of the algo it returns me 5

lyric mountain
#

ok so, what's the final goal?

civic scroll
#

wait that is macro?

eternal osprey
#
 System.out.println("SEEECOOOONNDD PAAAARRTTTT");
        for(int i = 0; i < boxPartitions.size(); i++){
            Vector<Vector<Double>> currentBox = new Vector<>();
            Vector<Vector<Double>> selectedBox = new Vector<>();
            selectedBox = boxPartitions.remove(i);
            currentBox.addAll(selectedBox);
            for(int j = 0; j < boxPartitions.size(); j++){
                if(i != j) {
                    if (isSmaller(selectedBox.get(0), boxPartitions.get(j).get(0))) {
                        currentBox.addAll(boxPartitions.get(j));
                        boxPartitions.remove(boxPartitions.get(j));
                        j = 0;
                        i = 0;
                    }
                }
            }
            boxPartitions.add(currentBox);
        }```
this part gotta be wrong
radiant kraken
#

what macro?

eternal osprey
radiant kraken
#

this aint rust sis

#

wait

civic scroll
#

then how?

lyric mountain
#

then you're overengineering it

radiant kraken
#

doesnt that only work for T[] things

#

not custom vectors

eternal osprey
#

A box fit, if there exists a permutation such that all dimensions of the box are bigger than the other:

box1: [x, y, z], box2: [x, y, z]
then it can be that [y,z,x] fits in [x, z, y]
as x > y, z> z, z> y

sharp geyser
#

Okay well

#

ima fix my bug after I wake up

#

cya guys

radiant kraken
#

gn

civic scroll
#

cya

civic scroll
eternal osprey
eternal osprey
radiant kraken
#

hm

#

wait is that actually possible for custom classes

#

some kind of operator fuckery or something

eternal osprey
#

i know it's overengineering but at this moment i really can;t afford to change it all over again

#

if you don't understand the code i can explain it to you for sure

radiant kraken
#

or is that only a compiler thing

civic scroll
#

ahh....

#

varivadic

radiant kraken
#

ahh icic

#

i rarely use C++ so onesieKEKW

eternal osprey
#

sorry for the bad code btw, i didn't clean anyting or tried optimizing it until it works completely

radiant kraken
#

i'm more towards C

sharp geyser
#

Okay but before I go to sleep

eternal osprey
#

i am just trying to get the right base set such that i can later on make it better

civic scroll
#

wait... what

sharp geyser
#
    vec.insert(0, 100);
    vec.insert(1, 1000);

    for(int i = 0; i < vec.length; i++) {
        std::cout << vec[i] << std::endl;
    }
0
100
1000

why this output that thonk

radiant kraken
#

i said go to bed

#

stop thinking about code

radiant kraken
sharp geyser
#

but if I dont figure this out

#

I wont be able to sleep

#

😔

eternal osprey
sharp geyser
#

for some reason it prints 0 at the beginning of everything

#

its starting to bother me

radiant kraken
#

we'll look at this tomorrow

sharp geyser
#

on another note before I go to bed

#

fixed my bug

civic scroll
#

@earnest phoenix WE OUT HERE 🗣️ 💯

sharp geyser
#

copied sayu's way of copying elements from the old array to the new array

for(int i = 0; i < this->length; i++) {
  std::cout << i << std::endl;
  new_array[i] = this->array[i];
}

but it needed to be this->length - i

civic scroll
#

wym

radiant kraken
sharp geyser
#

doing i < this->length for me caused problems

civic scroll
#

if you copy items from old array to new then would would you

sharp geyser
#

so changing it to this->length - i helped

radiant kraken
#

dafuq

sharp geyser
#

stroke?

radiant kraken
#

bru your code is broken

sharp geyser
#

I know I keep saying ima sleep but I still want to recap on what I've done and make sure my head is in the right place

neon leaf
#

E

radiant kraken
#

your head will be in the right place once you wake up

sharp geyser
#
void Vector::insert(int index, int element) {
  if(this->length == this->capacity) {
    this->capacity *= 2;
    std::realloc(this->array, this->capacity);
   }
   this->array[index] = element;
   this->length += 1;
}

So from my understanding

  1. Checking to see if the length of the array has reached the capacity
  2. If it has realloc the array so it can handle a higher cap
  3. If the check is false just add an element and increment the length
radiant kraken
sharp geyser
#

oh?

#

You said I did

radiant kraken
#

the for loop after realloc is useless

sharp geyser
#

Really?

radiant kraken
#

the memory block is just expanded

#

yes

sharp geyser
#

I see

#

Actually you're right

#

idk what I was thinking

#

😔

#

I just need to expand the capacity if the length has reached the cap

#

no need to make a new array

#

Well damn

#

thats much shorter now

civic scroll
sharp geyser
#

Well now that my mind has been put to ease

#

good night / morning guys

civic scroll
#

gn

sharp geyser
#

FUCK NO

#

You couldn't pay me enough

civic scroll
#

have a nice dream about kernel segfaults

radiant kraken
#

when you use 🚀Rust🚀

civic scroll
radiant kraken
#

imagine using unsafe

#

cant be me

civic scroll
radiant kraken
earnest phoenix
civic scroll
green kestrel
#

oooooo C++ dev stuff

sharp geyser
#

How’ve you been brain

green kestrel
#

good ta

#

finally got my database layer refactored in my latest bot!

#

been meaning to do this since sporks, never had opportunity

#

now uses prepared statements, and caches the statment handles

#

so if you do the same query twice, it absolutely stonks

#

ive seen so many sql libs, and some dont even do prepared statements, those that do, they dont seem to remember the statement ids

#

so they will always re-prepare each time anyway, defeating the point

sharp geyser
#

You got it rough mmLol

green kestrel
#

lol yeah

#

C libs and raw pointers suck ass

#

why are you implementing your own vector? whats wrong with std::vector?

sharp geyser
#

Nothing

#

Just a learning experience

#

I’m new to c++

green kestrel
#

you tried making a bot in C++ yet?

sharp geyser
#

Funny enough I tried with your lib but gave up at step 1

green kestrel
#

lol

#

which step is step 1

#

download?

sharp geyser
#

I installed it with vcpkg and then tried using it in my project but it couldn’t find it I guess

green kestrel
#

im hoping to finish off my bot soon... just need to finish dashboard and premium stuff

#

its not as complex as sporks or triviabot, but the code for both bot and dashboard was written from scratch, chucked away all my technical debt

#

as such its much nicer!

sharp geyser
#

Oh nice man, sounds like a fun project

green kestrel
#

its like 20 lines

sharp geyser
#

Dayum you’re splitting off event handlers nice

#

I myself would of just did it all in the same file KEKW

green kestrel
#

yeah its nice when its done neatly

sharp geyser
#

I’m not very good at neat

wheat mesa
#

Isn’t this considered a bad way to seed randomness

sharp geyser
#

I didn't do much as I started it last night

sharp geyser
#

If it improves the code while also explaining those improvements go for it

#

I don't want to just be left in the dark on what its doing as this is a learning experience for me

radiant kraken
green kestrel
sharp geyser
#

That is indeed its original purpose

#

as dealing with ints seemed easier than any and all types

green kestrel
#

thats what templates are for

#

theyre easy when you get used to it

sharp geyser
#

Dont even know what templates are

green kestrel
#

i just added gif flattening to my bot, drove me nuts lol

#

basically if i just try and deal with a big animated gif, tesseract cant OCR it and the image recognition API tries to scan every frame and would cost me a ton

#

in some situations you do want to see every frame to see if someones "done a fight club" and hid pr0n in one frame, so you can yeet the image away

#

but in this case, no

radiant kraken
#

@green kestrel can you review this pull request

#

i haven't used C++ in like 2 years lol

sharp geyser
#

thanks null, I forgot to check if the index is out of bounds with the length of the array to begin with when inserting

#

also why size_t

wheat mesa
green kestrel
#

looks ok to me

wheat mesa
#

But a bit more powerful

green kestrel
#

im not sure about using std::realloc tho

sharp geyser
#

Also wait isn't index >= length counterintuitive? Unless I am misinterpreting the result

green kestrel
#

std::realloc is for use with malloc and free NOT new/delete

sharp geyser
#

shouldn't it be <=

wheat mesa
green kestrel
#

iirc theres no "reallocate" for new

wheat mesa
#

(Or if I’m wrong brain can correct me)

green kestrel
#

yes

wheat mesa
#

It’s usually used for indexing

#

Kinda the standard

green kestrel
#

size_t is the correct size to cover a 64 bit size on a 64 bit system or 32 bit size on a 32 bit system

wheat mesa
#

It’s the same as usize in rust

green kestrel
#

yes

#

be aware of integer over/underflow though!

sharp geyser
#

should I use malloc over new?

green kestrel
#
size_t x{0};
x -= 1;
// x == 18446744073709551615
#

this can really bite you in the ass, if you accidentally decrement a loop counter below 0

#

C++ will not hold your hand, it wont throw, it'll just silently wrap

wheat mesa
green kestrel
#

no

#

no it does not!

wheat mesa
#

Does it not?

green kestrel
#

never use malloc!

sharp geyser
green kestrel
#

if you malloc a class its constructor is NOT called

#

if you new a class, it is

wheat mesa
#

Well I meant more or less for allocating memory blocks

green kestrel
#

similarly, this means its destructor is not called either if you free()

wheat mesa
#

I suppose that’s a good point though

green kestrel
#

which means RAII breaks

#

there is placement new though! 🙂

wheat mesa
#

C didn’t have all that fun stuff so it makes sense that new and delete didn’t exist

sharp geyser
#

So using realloc with new is not good?

green kestrel
#

placement new is where you can allocate your memory however you like, with malloc, with a magic spell from hogwarts, however, then you placement-new an object at a specific address and it calls its constructor

wheat mesa
#

afaik for this case it’s probably fine since you’re not using templates and only supporting integers

green kestrel
wheat mesa
#

man

#

I’ve been lied to my whole c++ life

sharp geyser
#

I see

#

so I should use delete to free it from memory and remake the array?

green kestrel
#

you gotta use malloc, if you want to use realloc, but be aware it wont call constructors, or you can use new/delete and memcpy

#

i'd do new, memcpy the whole array to new location, and then delete[] old array

sharp geyser
#

I see

green kestrel
#

im curious now how std::vector does it

radiant kraken
#

SHIT I FORGOT A DESTRUCTOR ia_why_sob

green kestrel
#

as it certainly doesnt copy the whole thing on reallocation

#

ah it does!

#
Notes: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. It is guaranteed that no reallocation takes place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the size specified in the most recent call to reserve().
#

so if you go past the reseved vector size, all elements are reallocated and any held references to them are invalidated

#

if you stay within the reserved size, it wont reallocate

radiant kraken
sharp geyser
#
void Vector::insert(int index, int element) {

    int *old = nullptr;

    if(this->length == this->capacity) {
        this->capacity *= 2;

        memcpy(old, array, capacity);
        
        delete[] array;
        
        array = old;
    }

    this->array[index] = element;

    this->length += 1;
}

So would something like this be correct? memcpy takes in a destination, source and a size. I set the dest to be a placeholder and then I set the source to be the current internal array and its capacity to be the new capacity. then I delete the old array and set it to be the new modified one.

green kestrel
#

btw

#

std::reallocate is allowed to do exactly this under the hood

#

so in that case you dont gain anything

sharp geyser
#

Oh?

green kestrel
#

yup

radiant kraken
#

wait is std::reallocate a thing

copper osprey
sharp geyser
radiant kraken
#

yes

green kestrel
#
realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails the original block is left untouched - it is not freed or moved. 
green kestrel
wheat mesa
#

Something I’ve been confused about recently, how does delete[] know when to stop freeing memory? How does it know how much memory belongs to the pointer it is being used on? Is this something that is handled by the allocator via storing extra info about a specific address?

sharp geyser
#

gotcha

radiant kraken
#

so what should i do for pointers allocated with new[]

#

if i want to reallocate

green kestrel
radiant kraken
#

should i not use realloc

green kestrel
#

memory allocators keep record of allocations

wheat mesa
#

I see

green kestrel
#

if you accidentally did delete a, its a memory leak at best, corrupted heap at worst

#

gotta remember not not mix up delete[] and plain delete

wheat mesa
#

Wouldn’t this make memory leaks relatively “detectable”…?

copper osprey
radiant kraken
#

not really

green kestrel
#

which has always irked me as like i said, it knows the size of what you allocated, i guess its to be sure it can call dtors of all elements in an array...

radiant kraken
#

especially if your codebase is hella complex

green kestrel
#

if you want to detect memory leaks, use valgrind

wheat mesa
wheat mesa
green kestrel
#

getting used to valgrind and gdb is one of the best things you can do for your sanity in C++ land

sharp geyser
radiant kraken
#

wdym

sharp geyser
#

I merged the pull request, and then pulled the code to my workspace and it is all unreachable

#

inside the if index >= length block

radiant kraken
#

bru i didnt tell u to merge it already

wheat mesa
#

Sometimes the editor/language server goes crazy

#

Restart your editor

sharp geyser
radiant kraken
#

i wanted for Voltrex to review it first

sharp geyser
#

brain is just as good as voltrex

radiant kraken
#

way better even mmLol

sharp geyser
#

Still kind of weird how the code is seemingly unreachable

radiant kraken
#

he's been doing C++ longer than most of us have been alive

copper osprey
wheat mesa
#

I wish I had more time to actually program things

#

I have a whopping one class that I actually write code in

sharp geyser
#

hey null

radiant kraken
#

hey misty

sharp geyser
#

did you test this code before making a pr

radiant kraken
#

yes

sharp geyser
#

I am wondering how

#

cause I cam getting link errors out the wazoo

wheat mesa
#

Misty your editor is probably spazzing out

#

Lemme see

radiant kraken
#

^

sharp geyser
#
====================[ Build | Vector | Debug ]==================================
"C:\Program Files\JetBrains\CLion 2023.2.2\bin\cmake\win\x64\bin\cmake.exe" --build C:\Dev\Vector\cmake-build-debug --target Vector -j 18
[1/3] Building CXX object CMakeFiles/Vector.dir/Vector.cpp.obj
[2/3] Building CXX object CMakeFiles/Vector.dir/main.cpp.obj
[3/3] Linking CXX executable Vector.exe
FAILED: Vector.exe 
cmd.exe /C "cd . && C:\PROGRA~1\LLVM\bin\CLANG_~1.EXE -fuse-ld=lld-link -nostartfiles -nostdlib -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -g -Xclang -gcodeview -Xlinker /subsystem:console CMakeFiles/Vector.dir/main.cpp.obj CMakeFiles/Vector.dir/Vector.cpp.obj -o Vector.exe -Xlinker /MANIFEST:EMBED -Xlinker /implib:Vector.lib -Xlinker /pdb:Vector.pdb -Xlinker /version:0.0   -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames  && cd ."
lld-link: error: undefined symbol: public: __cdecl Vector<int>::Vector<int>(void)
>>> referenced by C:\Dev\Vector\main.cpp:6
>>>               CMakeFiles/Vector.dir/main.cpp.obj:(main)

lld-link: error: undefined symbol: public: void __cdecl Vector<int>::insert(unsigned __int64, int)
>>> referenced by C:\Dev\Vector\main.cpp:8
>>>               CMakeFiles/Vector.dir/main.cpp.obj:(main)
>>> referenced by C:\Dev\Vector\main.cpp:9
>>>               CMakeFiles/Vector.dir/main.cpp.obj:(main)

lld-link: error: undefined symbol: public: int & __cdecl Vector<int>::operator[](unsigned __int64) const
>>> referenced by C:\Dev\Vector\main.cpp:14
>>>               CMakeFiles/Vector.dir/main.cpp.obj:(main)

lld-link: error: undefined symbol: public: __cdecl Vector<int>::~Vector<int>(void)
>>> referenced by C:\Dev\Vector\main.cpp:18
>>>               CMakeFiles/Vector.dir/main.cpp.obj:(main)
>>> referenced by C:\Dev\Vector\main.cpp:18
>>>               CMakeFiles/Vector.dir/main.cpp.obj:(?dtor$11@?0?main@4HA)
CLANG_~1: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
wheat mesa
#

Oh

copper osprey
#

can anypne help me pls?

sharp geyser
wheat mesa
#

Separating templates between .h and .cpp files gets messy

sharp geyser
#

when someoen can help they will

wheat mesa
#

Idk why, brain can probably explain

copper osprey
sharp geyser
#

Okay and

wheat mesa
#

I just know I have a lot of issues doing that

copper osprey
radiant kraken
#

true

wheat mesa
#

Someone will respond to you when they do

#

Just be patient

copper osprey
wheat mesa
#

You asked your question 10 minutes ago and have been spamming for the last 5 minutes for someone to help, I would be surprised if someone even responded within the hour

radiant kraken
#

i did this pull request a few minutes before i went for school so apologize if i fucked up iara_why_sob

sharp geyser
#

not at all

#

you're fine

radiant kraken
#

i tested it on a single cpp file and it worked lmao

#

don't know why linking doesn't work

green kestrel
#

you didnt inline it?

#

im guessing, im tired

sharp geyser
#

What exactly does that mean?

green kestrel
#

need inline on it, if it has no body and no presence in the cpp file, only the header

radiant kraken
#

all functions should be defined in the cpp file, no?

green kestrel
#

for templates, no

#

template functions/classes are generally inlined

#

this is the one with the pr where templates were added yes?

sharp geyser
#

yea

#

I merged the pr

radiant kraken
#

smh without brain/volt reviewing

sharp geyser
#

he said it looked fine

#

😭

radiant kraken
#

wtf man

#

oh well

#

can you inline it yourself? @sharp geyser

sharp geyser
#

I dont entirely understand inline

#

so maybe

radiant kraken
#

like merge the function definitions in Vector.cpp with the class definition in Vector.h to Vector.h

sharp geyser
#

but I will have to read into it

radiant kraken
#

like
Vector.h:

template<typename T>
class Thing {
public:
  void thing();
}

Vector.cpp:

template<typename T>
void Vector<T>::thing() { ... }

into (in Vector.h):

template<typename T>
class Thing {
public:
  void thing() { ... }
}

and delete the Vector.cpp file

#

@sharp geyser

sharp geyser
#

I see now

#

but I am not quite sure I understand why is there even the need of a cpp file if you can just do it all in the header file

radiant kraken
#

when your project grows more advanced, your code needs to be split in several cpp files

#

and those cpp files can depend on each other

#

whether your library be done through only headers or done through linking is only a matter of preference tho

#

for some reason templates cant be done through linking (as Brain said) soooo

sharp geyser
#

really?

#

So you are kind of forced to do it all in a header file if you are using templates

radiant kraken
#

yes

sharp geyser
#

that seems kinda bogus

radiant kraken
#

true

#

idk ask the c++ standard guy @earnest phoenix

sharp geyser
#

also

#

~Vector() is a deconstructor right?

#

its called when its destroyed or smth

radiant kraken
#

yes, it's a destructor

#

it's for freeing/deleting things like pointers allocated with malloc/new

#

it's called implicitly for you whenever your object goes out of scope

sharp geyser
#
Vector() : capacity(1), length(0), array(new int[1]) {};
explicit Vector(size_t size) : capacity(size), length(1), array(new int[size]) {};

so what exactly is this called?

#

I didn't know you could do Vector : prop()

radiant kraken
#

yes

#

it's only possible on constructors though

sharp geyser
#

Is that just a way of initializing properties easier?

#

I see

radiant kraken
#

yes, it also allows for polymorphism (like extends in JS)

sharp geyser
#

@solemn latch fix automod grrr

#

I can't even post c++ error messages without it saying it is harmful

radiant kraken
#

i mean

#

C++ error messages are harmful mmLol

solemn latch
#

it thinks its a phone number 👀

sharp geyser
#

bruh

#

how

radiant kraken
#

bru

sharp geyser
#

Access violation error

#

Won't tell me much else of where its happening

solemn latch
#

stop posting phone numbers angeryBOYE
lol

radiant kraken
#

whats in Vector.h

sharp geyser
#
//
// Created by dyeaaaronjr on 11/13/2023.
//

#ifndef VECTOR_VECTOR_H
#define VECTOR_VECTOR_H

#include <stdexcept>

template <typename T>
class Vector {
  T *array;
  size_t capacity;
  size_t length;

 public:
  Vector() : capacity(1), length(0), array(new int[1]) {};
  explicit Vector(size_t size) : capacity(size), length(1), array(new int[size]) {};

  constexpr size_t size() { return length; }

  inline void push_back(T element) { insert(length, element); }
  void insert(size_t index, T element) {
      if (index >= length) {
          int* old = nullptr;

          if (length >= capacity) {
              capacity *= 2;

              memcpy(old, array, capacity);

              delete[] array;

              array = old;
          }

          array[index] = element;
          length = index + 1;
      }
  }
  T &operator[](size_t index) const {
    if (index >= length) {
        throw std::range_error("index out of range");
    }
    return array[index];
  }
  ~Vector() {
      delete[] array;
  }
};

#endif  // VECTOR_VECTOR_H
#

Basically just what you told me to do, which is merge cpp to .h

radiant kraken
#

why did u change insert

sharp geyser
#

cause brain said no use realloc with new

#

use memcpy with delete

radiant kraken
#

bru okay

sharp geyser
#

I wish the debugger told me more

radiant kraken
#

change int* old with T* old and memcpy(old, array, capacity); with memcpy(old, array, capacity * sizeof(T));

sharp geyser
#

I see

radiant kraken
#

also put array[index] = element; after the if statement

sharp geyser
#

Okay

radiant kraken
#

and the capacity *= 2; should be in a while loop like the one i did in my pr

#

okay that's enough suggestions

sharp geyser
#

Why in a while loop?

radiant kraken
#

like what if someone does

vec.insert(0, 200);
vec.insert(4, 600);
vec.insert(9836362, 900);
#

afaik there's a mathematical way to do ```cpp
while (capacity < length) {
capacity *= 2;
}

sage bobcat
#

One message removed from a suspended account.

radiant kraken
#

SIS I AM AT SCHOOL

sharp geyser
#

Also

sage bobcat
radiant kraken
#

because i have to

sage bobcat
#

One message removed from a suspended account.

sharp geyser
#

None of this really fixes the obscure error of (0xC0000005) 😭

#

Why are C++ errors so obscure

radiant kraken
#

it's 07:35

#

am

sharp geyser
#

If it was better I might be able to fix it myself

radiant kraken
#

@sharp geyser what's in Vector.h now

sharp geyser
#
//
// Created by dyeaaaronjr on 11/13/2023.
//

#ifndef VECTOR_VECTOR_H
#define VECTOR_VECTOR_H

#include <stdexcept>

template <typename T>
class Vector {
  T *array;
  size_t capacity;
  size_t length;

 public:
  Vector() : capacity(1), length(0), array(new int[1]) {};
  explicit Vector(size_t size) : capacity(size), length(1), array(new int[size]) {};

  constexpr size_t size() { return length; }

  inline void push_back(T element) { insert(length, element); }
  void insert(size_t index, T element) {
      if (index >= length) {
          T* old = nullptr;

          if (length >= capacity) {
              while(capacity < length) {
                  capacity *= 2;
              }

              memcpy(old, array, capacity * sizeof(T));

              delete[] array;

              array = old;
          }
          length = index + 1;
      }

      array[index] = element;
  }
  T &operator[](size_t index) const {
    if (index >= length) {
        throw std::range_error("index out of range");
    }
    return array[index];
  }
  ~Vector() {
      delete[] array;
  }
};

#endif  // VECTOR_VECTOR_H
wheat mesa
#

now implement remove and suffer with shifting :tf:

sharp geyser
#

😔

radiant kraken
#

um remove the T* old = nullptr; and add T* old = new T[capacity]; the line before memcpy

sharp geyser
#

Isn't that just making a new array of that type with the capacity ?

radiant kraken
#

yes

#

your code currently memcpys to a null pointer, which is a segfault

sharp geyser
#

damn IDE

radiant kraken
#

a null pointer must NOT be modified/dereferenced

sharp geyser
#

doesn't have my back

radiant kraken
#

but i have your back

sharp geyser
#

So uh

#

Shit happened

radiant kraken
#

bruuuuuhhhh

#

maybe this is what happens when u mix new with memcpy

#

idk @green kestrel

sharp geyser
#

according to brain its better to use memcpy when using new/delete

#

Unless I misunderstood him

radiant kraken
#

look i rarely use new/delete, i'm more used to malloc/free ia_why_sob

sharp geyser
#

I am used to neither

#

also doesn't help that it could literally mean a number of things

#

I am either freeing memory that is already freed, writing into memory that is unallocated or attempting to access elements in the memory that has already been freed according to stackoverflow

wheat mesa
#

memcpy simply reads the amount of bytes from one buffer and copies it into the other

radiant kraken
#

^

sharp geyser
#

I see

wheat mesa
#

the fact is that you're doing T* old = nullptr which means old is not allocated

#

you're then attempting to copy into memory that you don't own

sharp geyser
#

so it requires me to already have an allocated array in memory for it to copy to

radiant kraken
#

yes

wheat mesa
#

you need to allocate space in old in order to use memcpy on it

sharp geyser
#

Well that makes sense

#

but its already doing that now

radiant kraken
#

thats why i told u to use T* old = new T[capacity];

wheat mesa
#

show the current snippet

sharp geyser
#

and yet its causing a heap corruption

#
void insert(size_t index, T element) {
      if (index >= length) {
          if (length >= capacity) {
              while(capacity < length) {
                  capacity *= 2;
              }

              T* old = new T[capacity];

              memcpy(old, array, capacity * sizeof(T));

              delete[] array;

              array = old;
          }
          length = index + 1;
      }

      array[index] = element;
  }
wheat mesa
#

onto your next problem

#

old and array have different sizes

#

you're attempting to copy capacity * sizeof(T) bytes from array to old

#

it's reading past what array owns

radiant kraken
#

wait really?

wheat mesa
#

don't use memcpy here

radiant kraken
#

isnt array the same size

wheat mesa
#

why would it be?

#

this logic assumes that the length is greater than the capacity and therefore you must grow the array

radiant kraken
#

yes

wheat mesa
#

therefore array has a smaller size than capacity * sizeof(T) after you modify it

#
int oldCapacity = capacity;
while(capacity < length) {
  capacity *= 2;
}
T* temp = new T[capacity];

for (int i = 0; i < oldCapacity; i++) {
  temp[i] = array[i];
}

delete[] array;

array = temp;
#

try something more like that

radiant kraken
#

oooooooo

sharp geyser
#

I swear I was doing that before like way earlier

radiant kraken
#

i forgor sorry

sharp geyser
#

before people started recommending realloc and memcpy

#

😔

radiant kraken
#

not the for loop, tho

sharp geyser
#

yes the for loop

radiant kraken
#

you can still use memcpy here

wheat mesa
#

you can but I figured that memcpy would be a little more convoluted for understanding here

#

you just have to memcpy the amount of bytes that array actually owns, nothing more

sharp geyser
#

so instead of capacity * sizeof(T) would it not just be oldCapacity?

wheat mesa
#
int oldCapacity = capacity;
while(capacity < length) {
  capacity *= 2;
}
T* temp = new T[capacity];

memcpy(temp, array, sizeof(T) * oldCapacity);

delete[] array;

array = temp;
#

this would work

radiant kraken
#
size_t new_capacity = capacity;
while (length > new_capacity) {
  new_capacity *= 2;
}
// ...
T* old = new T[new_capacity];
memcpy(old, array, capacity * sizeof(T);
capacity = new_capacity;
sharp geyser
#

sorry forgot that capacity changes

radiant kraken
#

this actually

wheat mesa
#

the reason you need sizeof(T) here is because memcpy copies the exact amount of bytes, not elements, that you give it

radiant kraken
#

^

sharp geyser
#

hm

#

Either way a heap corruption still occurs

radiant kraken
#

or wait

#

nvm

wheat mesa
#

both in your main.cpp and in the snippet

sharp geyser
#
#include <iostream>

#include "Vector.h"

int main() {
  Vector<int> vec;

  vec.insert(0, 100);
  vec.insert(1, 1000);

//  vec.push_back(10000);

  std::cout << vec.size() << std::endl;

  for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i] << std::endl;
  }

  return 0;
}
  void insert(size_t index, T element) {
      if (index >= length) {
          if (length >= capacity) {

              int oldCapacity = capacity;

              while(capacity < length) {
                  capacity *= 2;
              }

              T* old = new T[capacity];

//              memcpy(old, array, oldCapacity * sizeof(T));
              for (int i = 0; i < oldCapacity; i++) {
                  old[i] = array[i];
              }

              delete[] array;

              array = old;
          }
          length = index + 1;
      }

      array[index] = element;
  }
wheat mesa
#

oh I see why this is unreachable

#

how would length ever be greater than capacity?

#

(if you're not incrementing it before you do the check?)

sharp geyser
#

See that's what I thought, but I also wasn't too sure

wheat mesa
#
void insert(size_t index, T element) {
  if (index >= length) {
    if (index >= capacity) {
      // grow the array
    }
    length = index + 1;
  }
  array[index] = element;
}
#

something more like that

#

the reason you're getting a memory corruption is because the array is never even growing with this logic

#

and then it assigns to memory that isn't allocated/it doesn't own

#

(the OS really dislikes that)

sharp geyser
#

I still don't think that will work

#

Unless I am just misunderstanding the code

wheat mesa
#

try it

#

if the index is greater than the length but within the allocated capacity of the array, you can just shove it into the array without needing to reallocate

#

if the index is greater than the capacity, then you need to reallocate to fit it

sharp geyser
#

Yea it still causes a heap corruption and then its not allowed to even go past the size of the initial array

wheat mesa
#

sorry I forgot to update the length both times

#

try that now

sharp geyser
#

Oh right

#

cause it shouldn't be length >= capacity

wheat mesa
#

yeah

sharp geyser
#

Huh

#

but it still produces the same result thonk

wheat mesa
#

lemme see exactly what you're writing

sharp geyser
#
  void insert(size_t index, T element) {
      if (index >= length) {
          if (index >= capacity) {

              int oldCapacity = capacity;

              while (capacity < length) {
                  capacity *= 2;
              }

              T *old = new T[capacity];

//              memcpy(old, array, oldCapacity * sizeof(T));
              for (int i = 0; i < oldCapacity; i++) {
                  old[i] = array[i];
              }

              delete[] array;

              array = old;
          } else {
              length = index + 1;
          }
      }

      array[index] = element;
  }

Am I still not understanding what you're saying?

wheat mesa
#

get rid of the else

#

just put the length = index + 1; outside of the else but within the first if

#

because either way your length should be the last element index + 1

sharp geyser
#

Okay so still heap corruption but it adds the elements appropriately

wheat mesa
#

wdym heap corruption still

sharp geyser
#

I still get a error that a heap corruption occured

wheat mesa
#

does it happen before or after the elements get inserted

sharp geyser
#

Seems to be after

wheat mesa
#

because if it happens after then your insert function is fine

#

something else is wrong

sharp geyser
#
  T &operator[](size_t index) const {
    if (index >= length) {
        throw std::range_error("index out of range");
    }
    return array[index];
  }

likely this then

#

or something related to it

wheat mesa
#

this looks fine

sharp geyser
#

Idk what else it could be then

#

cause I am only using .insert

#

and then looping over my newly created vec

#
  Vector<int> vec;

  vec.insert(0, 100);
  vec.insert(1, 1000);

//  vec.push_back(10000);

  std::cout << vec.size() << std::endl;

  for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i] << std::endl;
  }

main.cpp

wheat mesa
#

what about the size function

sharp geyser
#

I make a vector, insert into it, then loop over it

#

size just returns length

#
constexpr size_t size() { return length; }
wheat mesa
#

why's that constexpr?

#

and why does that compile...

radiant kraken
#

so that it's evaluated at compile-time?

sharp geyser
#

ask null, I forgot to ask about that specific thing

wheat mesa
#

but size isn't a compile time thing

sharp geyser
#

isn't it runtime?

radiant kraken
#

but it compiles though

wheat mesa
#

length is not constexpr, how can that function return a constexpr

#

that doesn't make sense

radiant kraken
#

it's like a const function in Rust

#

like when you do a len function in rust you tend to do this:

const fn len(&self) -> usize {
  self.len
}
wheat mesa
#

this does not make sense

#

mark the function as const, don't mark it as constexpr

#

I have no idea why that even works

radiant kraken
#

what

#

would that change anything

wheat mesa
#

I don't know, but it doesn't feel right

sharp geyser
#

Will that even fix the heap corruption issue

radiant kraken
#

no

wheat mesa
#

no

#

but still that feels extremely wrong

radiant kraken
#

the function does not change at all

wheat mesa
#

how would that even make sense

sharp geyser
#

I was about to say

wheat mesa
#

to be constexpr

#

the length completely depends on runtime info

#

btw I figured out what's wrong

#

you're never incrementing length

#

lol

sharp geyser
#
for (int i = 0; i < vec.size(); i++) {
    std::cout << vec[i] << std::endl;
  }

I have a feeling the issue occurs here.

radiant kraken
#

see smh

sharp geyser
#

am I not?

wheat mesa
#

in your insert function

#

you're only changing length if the array resizes

#

which doesn't always happen

sharp geyser
#

Oh my god

#

💀

wheat mesa
#

which would make sense because then length is always 0 here

radiant kraken
#

what if someone do this tho ```cpp
vec.insert(5, 3);
vec.insert(1, 2);

sharp geyser
#

That got removed when I pulled the pr

sharp geyser
#

So after array[index] = element; should I do length += 1;

radiant kraken
#

yes

wheat mesa
#
void insert(size_t index, T element) {
  if (index >= length) {
    if (index >= capacity) {
      // grow the array
    }
    length = index + 1;
  } else {
    length++
  }
  array[index] = element;
}
radiant kraken
#

or length++;

wheat mesa
#

no

#

well

#

I guess you could

#

you'd just have to change the length = index + 1 to length = index

sharp geyser
#

Hm

#

even with the else { length++ }

wheat mesa
#

no

#

not with the else

sharp geyser
#

sorry

#

I hit enter too soon

wheat mesa
#

haven't tested it tho

sharp geyser
#

to continue on, there is still a heap corruption somewhere

wheat mesa
#

can you push to your repo so I can look at the full thing

sharp geyser
#

Yep

wheat mesa
#

bet

radiant kraken
wheat mesa
#

real

sharp geyser
#

there

wheat mesa
#

you good if I make a PR to this?

radiant kraken
#

is that else should be there tho

#

like if the index is lower than length, the length still grows

sharp geyser
wheat mesa
#

you can reformat it if you wish, my formatter is a bit different from yours

sharp geyser
#

So wait

#

what was I doing differently than what you have

#

I dont see much differences

wheat mesa
#

the nested if statements were probably messing with the logic

sharp geyser
#

Ah

wheat mesa
#

it was a bit difficult to read, so this is simplified to be much easier to understand

#

don't be afraid to separate things into private methods, especially resizing behavior like this

#

helps the logical flow a lot

sharp geyser
#

Thanks

#

You helped a ton

wheat mesa
#

you know misty

#

that was my first ever PR

#

lmfao

sharp geyser
#

lmao

#

and it was on a bs project

wheat mesa
#

you're boosting my resume rn 😎

sharp geyser
#

hey man

#

Idm helping out a friend

#

Also

#

are things private by default?

#

I notice you didn't use private:

radiant kraken
#

yes

sharp geyser
#

interesting

radiant kraken
#

private: is useless lmao

wheat mesa
#

it's more for readability than anything

#

struct members default to public, class members default to private

radiant kraken
#

unless you define a struct, which is public by default afaik

sharp geyser
#

interesting

#

now to implement remove

#

should be simple

#

all I have to do is remove the element at a specific index and then shift all the elements up 1 I think

radiant kraken
#

Waffle have you read my message

wheat mesa
#

yes

#

idk

#

my brain is fried ngl

sharp geyser
#

So when removing something from the array, should I worry about modifying its capacity or should I just keep it at its current capacity

radiant kraken
#

@sharp geyser try removing that } else { length++; }

sharp geyser
#

why

#

the code works

wheat mesa
#

I fixed it in a pr

sharp geyser
#

I think I am now ready to tackle machine learning sunglas /s

wheat mesa
#

oh I see what you're saying

#

yeah you'll need to fix that

radiant kraken
#

smhhhh

wheat mesa
#

I didn't test much

#

that's the consequences of it

sharp geyser
#

Well all i am happy is that it works now

#

despite me requiring your guys help a lot

#

😔

radiant kraken
#

did you remove it

wheat mesa
#

it will break if you try to add in a reverse order unfortunately

sharp geyser
#

yea

wheat mesa
#

there you go

sharp geyser
#
6
100
-842150451
1005
-842150451
1000
10000
wheat mesa
#

you didn't initialize the memory

sharp geyser
#
  vec.insert(0, 100);
  vec.insert(4, 1000);
  vec.insert(2, 1005);

  vec.push_back(10000);
#

I also did this

wheat mesa
#

you need to fix the ctor

sharp geyser
#

Wanted to see what would happen

radiant kraken
#

elements at index 1 and 3 are uninitialized

wheat mesa
#

it's doing what it's meant to do but the memory is just garbage before you allocate it

radiant kraken
#

so they are random blobs of RAM

sharp geyser
#

yea

#

I know

wheat mesa
#

actually now that I think about it shouldn't it be not doing that?

#

since you're allocating with new?

radiant kraken
#

yes

#

maybe after new you should memset the entire thing to 0 mmLol

wheat mesa
#

no no

#

that's a bad idea

sharp geyser
#

I think the issue is I am telling it to insert something at index 4 when 1 and 3 are basically nothing

wheat mesa
#

because that overwrites the data set by the constructor

#

(if there is one)

radiant kraken
#

i mean

#

in the constructor

wheat mesa
#

I know

#

I'm saying that's a bad idea

sharp geyser
#

Honestly does it matter if that happens?

radiant kraken
#

some libraries/languages do this

wheat mesa
#

Because then the entire block is 0s even though the user may be expecting a different behavior

#

Yes

#

Because new will invoke the parameterless constructor of T

sharp geyser
#

I am talking about it just putting random junk in the place of index 1 and 3

radiant kraken
#

ooo smh

wheat mesa
#

And if you overwrite everything with 0 after that, you'd be potentially messing with data that was set by the default constructor of T

radiant kraken
#

i forgot that we're not using malloc again

#

pov you're a c dev

sharp geyser
wheat mesa
#

Yes it does

sharp geyser
#

hm

wheat mesa
#

I think most people would be expecting it to be filled with zeroes for the case of integers

sharp geyser
#

fair enough

radiant kraken
#

then in that case ```cpp
if (index >= length) {
throw std::range_error("out of range");
}

wheat mesa
#

this is going to look very cursed but just try it...

sharp geyser
#

So should I just fill it with 0s to begin with and then whenever they insert it changes the value at that index

wheat mesa
#

in your constructor change array(new int[1]) to array(new int[1]()) and do the same when resizing

#

or sorry not new int

#

new T

#

is what I meant

radiant kraken
#

what does the parentheses do

sharp geyser
#

Im not quite sure what they do either

wheat mesa
radiant kraken
#

that's nice

sharp geyser
#

I see

radiant kraken
#

it's only good if T is not a struct/class with a constructor, no?

sharp geyser
#

That is nice

wheat mesa
#

well, if T has a parameterless ctor then it's fine

radiant kraken
#

oh okay

sharp geyser
#

Honestly not trying to fix every use case

#

just trying to implement a vector

#

😔

radiant kraken
#

ok well ignore this

#

lets get to implementing a remove function

sharp geyser
#

remove should be easy

#

all it is just removing at an index and then shifting the array elements up 1 to take the spot of the removed no?

radiant kraken
#

yes

#

you can use a for loop or a memset

sharp geyser
#

time to look at what memset is

wheat mesa
#

memset just sets a block of n bytes to whatever value you tell it to

radiant kraken
#

it's basically a glorified for loop + assignment

wheat mesa
#

memset(pointer_to_array_of_10_ints, 0, sizeof(int) * 10) will set an array of 10 ints to 0

sharp geyser
#

I see

radiant kraken
#

(in the byte level, NOT in the int level)

wheat mesa
#

^^

radiant kraken
#

WAIT mb not memset

#

i meant memcpy

#

i cant focus shdhagzgxfssf

sharp geyser
#

why use memcpy here?

radiant kraken
#
memcpy(&array[index_to_remove],  &array[index_to_remove + 1], (length - index_to_remove + 1) * sizeof(T));

try something like this

#

i hope this is right

sharp geyser
#

hm

#

so from my understanding

#

the destination is a reference of the array at that index, then the source is the reference at the index + 1, and then we are changing the size to be the length - index_to_remove + 1

#

why is it + 1 for the source?

radiant kraken
#

because we want to move all elements after the index into the current index?

sharp geyser
#

If you are able to explain it better than I please do

#

cause I am not sure I follow the entirety of it

radiant kraken
#

@wheat mesa can u explain this

sharp geyser
radiant kraken
#

it copies the entire memory after the index into said index

wheat mesa
#

ok so basically arrays are a continuous block of memory

radiant kraken
#

and then you just length--;

cinder aurora
#

Perdón we pero a mi me lo mandaron. Lamento tener que enviarte esto, pero ahora que lo has abierto no puedes dejar de leerlo. Hola, mi nombre es Teresa Fidlago. Mori 27 años. Si no envías esto a 20 personas, dormiré a tu lado para siempre. Si no me crees, búscame. Teresa Fidlago. Entonces envíe esto a 20 personas. Una niña ignoró esto y su madre murió 20 días después. NO ENVIE ATRÁS!!!. Lo siento, tuve que enviar esto. Por cierto, esto no es falso buscarla en google. Alguien me envió esto y tuve que hacer lo mismo, no me arriesgo a ignorar este mensaje, dime por qué esto sigue sucediendo, otra abuela leyó esto y se lo envió a 20 personas, pero el Internet se fue cuando se lo habia mandado a 19. Fue encontrada cortada en 5 piezas después de 1 día. Asegúrate de enviarlo.

radiant kraken
#

this guy explains it better than i do

wheat mesa
#

the first argument is saying that you want to copy into the location of the element you want to remove

#

array[index_to_remove] being the value of the item, &array[index_to_remove] being where that value lives at

#

and you're copying from the next element onwards

radiant kraken
#

the first argument is the destination, the second argument is the source being the starting block of memory to copy from, and the third argument is the amount of bytes to copy

wheat mesa
#

for (length - index_to_remove + 1) * sizeof(T) bytes

sharp geyser
#

So basically

#

I am telling it to just copy the array of the next element after the one being removed to the destination of the removed

radiant kraken
#

yes

sharp geyser
#

so it kind of cancels each other out removing the element but leaving behind everything else?

#

Okay so it removes the element thats nice

#

but I am running into a heap corruption, which is probably because I am not doing any checks so that is to be expected

#

at least I can confirm it works beyond that, didn't know memcpy could be used like that

radiant kraken
sharp geyser
#

yea

radiant kraken
#

and checks whether index_to_remove is not 0 and less than the length

sharp geyser
#

but what if they want to remove the element at index 0

radiant kraken
#

well the same applies

sharp geyser
#

are arrays in c++ not 0 based?

radiant kraken
#

they are zero based

sharp geyser
#

bout to say

sharp geyser
#

But yea

#

hm

#

Also

#

I just realized

#

I have been coding for hours straight

#

I haven't done that in a while

#

Okay man

#

why the fuck is there a heap corruption

radiant kraken
#

ahshshsjdnddnbxxgcgf

#

can i see ur code

sharp geyser
#

I hate C++ right now