#why is this expression not modifiable

191 messages · Page 1 of 1 (latest)

unique copperBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

left owl
#
struct Entry {
  char *word;
  unsigned count;
};

struct Bucket {
  unsigned numEntries;
  Entry *entries[BUCKET_LENGTH];
};

#

the line

bucket->entries=NewEntries;
#

invali

#

invalid

#

expression must be a modifiable lvalue

#

why?

rustic ridge
#

entries is an array which you cannot overwrite with simple assignment.

left owl
#

i made a new one

#

can i not assign another pointer to that array postiion

rustic ridge
#

It's the equivalent of

int ia[42];
ia = new int(100);

can't change the array like that.

#

If you meant an array position then you have to add the position.

left owl
#

is that not the position?

#

bucket->entries

rustic ridge
#

Like bucket->entries[position] = NewEntries;.

left owl
#

but bucket>etries[position] has entry

#

not the array of entries

#

am i dumb

rustic ridge
#

It seems like what you really want is to change the type of bucket->entries to std::vector<Entry>.

left owl
#

cant

#

cannot use vector

rustic ridge
#

Alternatively if you want to change the array that is bucket->entries you have to use Entry* instead of Entry[].

left owl
#

so i think the solution is delete old array and make new one

rustic ridge
#

Yeah, except just like with ia up there you can't do that when it's an array.

left owl
#

oh

#

wait

rustic ridge
#

Gotta change it to a pointer that points to some number of Entrys.

left owl
#

Entry *NewEntries= new Entry[bucket->numEntries+1];

#

is this not already a pointer?

rustic ridge
#

It is and that part is fine.

#

But bucket->entries is not a pointer.

left owl
#

huh

#

what should i do

#

if icant replace the array

rustic ridge
#

The way I see it, entries is a bucket of entries. It's not just entries. So bucket->entries=NewEntries is incorrect, because you're assigning entries to a bucket of entries. The types don't match and the logic doesn't work out. bucket->entries[position] = NewEntries; is correct because you're putting entries in the bucket of entries.

#

The bucket never changes, only the entries that are in the bucket.

left owl
#

newEntry is the entry

#

sorry for bad naming

#
  Entry *newEntry= new Entry;
  newEntry->count=1;
  newEntry->word=NewWord;
  Entry *NewEntries= new Entry[bucket->numEntries+1];
rustic ridge
#

I think that is basically right, except "newEntry is the entries", plural.

left owl
#

did i initialize it wrong

rustic ridge
#

I think new Entry[bucket->numEntries+1]; is not correct. The number of entries should not depends on the bucket size.

left owl
#

wdym by that

rustic ridge
#

Anyway, the solution is to read again what the purpose of this is. I feel like the point is to make a bucket of entries, as in the bucket holds lists of entries. NewEntry is a list of entries and gets put in the bucket. The bucket is not a list of entries, it's a list of lists of entries. But I just pieced that together from the variable names, you probably have a text description that explains this properly.

left owl
#

yeah

#

bucket has an array of entries

#

dynamic

#

and the num of entries is length of the array basically

#
bool bucketInsert(Bucket *bucket, const char *word, unsigned int count) {
  bool hasNewEntry = false;
  Entry *entry = bucketFind(bucket, word);
  // TODO BEGIN
  if(bucket->numEntries>=BUCKET_LENGTH){
    return hasNewEntry;
  }
  if(entry!=nullptr){
    entry->count=count;
    return hasNewEntry;
  }
  // get past this point
  int size=strlen(word);
  char *NewWord=new char[size];
  strcpy(NewWord,word);
  Entry *newEntry= new Entry;
  newEntry->count=1;
  newEntry->word=NewWord;
  Entry *NewEntries= new Entry[bucket->numEntries+1];
  if(bucket->numEntries>0){
    for(int i=0;i<bucket->numEntries;i++){
      NewEntries[i]=bucket->entries[i];
    }
    delete[] bucket->entries;
  }
  NewEntries[bucket->numEntries]=newEntry;
  bucket->entries=NewEntries;
  bucket->numEntries++;
  hasNewEntry=true;
  // TODO END
  return hasNewEntry;
}

my code is basically if it gets past that point that means it needs to create a new entry

#

logic is correct

#

i just had a memory leak

rustic ridge
#

Bucket has an array of entry pointers, not entries. And I think the point of that is that bucket has a list of variable-many entries.

left owl
#

yeah entry pointers

#

mb

#

but i did create an array of entry pointers did i not

rustic ridge
left owl
#

if i initialize it to higher then the amount of entries

#

doesnt that cause memory leak

rustic ridge
#

You can't initialize it to something higher the way you imagine. It's an array with a fixed size and its size cannot change.

left owl
#

huh

rustic ridge
#

But the entry*s inside can point to more than 1 entry.

left owl
#

yeah

#

man im confused

rustic ridge
#

I think the key is that bucket->entries is not a list of entries but a list of lists of entries. Then it should start making sense.

left owl
#

wdym by list of lists

#

what is the original lists

rustic ridge
#

Entry* is a list of entries, you dynamically allocate the number of entries you want with new.

left owl
#

yes

rustic ridge
#

Entry*things[123]; is a list of 123 entry lists.

#

The length of things is fixed, you always have exactly 123 entry lists.

#

Some of them may be nullptr or something.

left owl
#

struct Entry {
char *word;
unsigned count;
};

#

ohh

#

so entry is a list?

#

is that what you mean

#

that entry

rustic ridge
#

No, Entry is not a list, only a single entry.

left owl
#

ok

#

i dont get the second list part

#

sorry

rustic ridge
#

Entry * is not just a pointer to an entry though, Entry * points to something like new Entry[count] and therefore points to count entries, so it's basically a list of entries.

left owl
#

ye

#

thats a list of entries

#

wheres the list of list

rustic ridge
#
Entry entry; //single entry
Entry *entries; //list of entries
Entry *bucket[213]; //list of lists of entries
left owl
#
  unsigned numEntries;
  Entry *entries[BUCKET_LENGTH];
};
#

bucket has its own initializatio

#

bucket is bucket

rustic ridge
#

I think the naming is just dumb.

left owl
#

yeah well

#

i didnt name it

rustic ridge
#

numEntries is incorrect, it should be numEntryLists.

#

And it should be Entry *bucket[BUCKET_LENGTH];.

#

The bucket has the length bucket length.

#

It's understandable if you confuse the bucket with lists since apparently your teacher also confused them.

left owl
#

wait

#

its just 128

rustic ridge
#

Yeah, it has to be a number known at compile time because C++ says so.

left owl
#

wait

rustic ridge
#

And it can't change.

left owl
#

its not a dynamic array

#

holy shit

#

im sostupid

rustic ridge
#

Right

left owl
#

what am i doing

rustic ridge
#

It's a fixed array of dynamic arrays 😄

left owl
#

the entry is the dynamic array right?

rustic ridge
#

Maybe. I lost track of which entry you mean.

left owl
#

when i say entry i just mean the Entry struct

rustic ridge
#

Entry is just a single entry.

#

No list

left owl
#

the word inside it is dynamic

rustic ridge
#

Sure, but it's still only 1 entry.

left owl
#

what is the dynamic array then

rustic ridge
#

Entry *

left owl
#
struct Bucket {
  unsigned numEntries;
  Entry *entries[BUCKET_LENGTH];
};
#

this?

rustic ridge
#

That's not exactly an Entry *, that's an array of Entry *s.

#

In other words, a list of lists of entries.

left owl
#

but its fixed right

rustic ridge
#

Yes, there is a fixed number of entry lists.

left owl
#

so no dynamic?

rustic ridge
#

The entry lists are dynamic.

#

A fixed number of lists, but each list has a dynamic number of entries.

left owl
#

wait

#

each of them is a list??

rustic ridge
#

Yes

#

You could theoretically put all entries in the same list, but there is probably a purpose to keeping them separate.

#

Maybe all the entries where the word starts with a goes into one list in the bucket and so on.

left owl
#

its not a list though

#

i cant access it

#

no list of list

#

unless vsc is acting up

#

its just a fixed array of a single entry

#

in each index

rustic ridge
#

bucket->entries[0]; should be the first entry list.

left owl
#

no

#

its just an entry

#

in bucket->entries[0]

#

its just an entry

rustic ridge
left owl
#

ok

rustic ridge
#

Ignore the squigglies, try to compile and look at the compiler's error message.

#

The squigglies are shortened and sometimes wrong.

rustic ridge
# left owl

I think I see a . at the end instead of a ;. Maybe that's the problem.

left owl
#

no

#

i havnet put ; yet

#

if you type bucket.[something] it will autoconvert it

#

into the arrow

rustic ridge
#

Well, bucket->entries[1].if is invalid syntax, so it complains.

left owl
#

is easier to type

#

itll auto convert it

#

thats not the error im talking about

rustic ridge
#

Yeah, makes sense, because bucket is a Bucket *, right?

#

So bucket. doesn't work, pointers don't have .something.

left owl
#

it converts it to ->

rustic ridge
#

So your IDE thinks you must have meant bucket-> which makes sense.

left owl
#

same thing

#

after i click enter it turns to ->

#

just shortcut

rustic ridge
#

The -> is correct, I don't see the problem.

left owl
#

there is no problem

#

im just saying its not a list of entries

#

inside of bucket->entry[0]

rustic ridge
#

Well, true, bucket is a pointer to 1 Bucket which contains an array of Entry *s which each point to a variable number of Entrys.

#

bucket->entry[0] should be an Entry*.

left owl
#

ok ima try to find my error

#

some segmentation shit

rustic ridge
#

Chances are that bucket->entries[0] is invalid because you didn't put a list in yet.

#

That's the purpose of unsigned numEntries;. Technically bucket->entries is a fixed size array, but practically only some lists are logically valid and numEntries probably says that the first numEntries lists are valid.

#

And chances are numEntries starts out with 0.

#

So before you can access a list you have to create a list, assign it and adjust numEntries.

rustic ridge
#

Well, you have

struct Bucket {
  unsigned numEntries;
  Entry *entries[BUCKET_LENGTH];
};
#

Clearly numEntries tells us how many entries are in Bucket.

#

But also, the number of entries are fixed, it's BUCKET_LENGTH. Doesn't make any sense.

#

So it must be for something else.

#

I assume it's for saying that numEntries values in entries are valid and the rest are garbage.

#

To keep track of what's in entries.

left owl
#

The amount of used entries

#

Yeah

rustic ridge
#

Or maybe it expresses the length of the lists. Who knows.

left owl
#

It’s the amount of valid entries

left owl
#

Is the thing

#

Unless I’m dumb

rustic ridge
#

So far you haven't accessed it, no. But I assume your task requires you to do so eventually.