Discussion:
Resizing Arrays
(too old to reply)
Nigel Mackay
2007-09-23 09:44:07 UTC
Permalink
Hi

I understand that arrays cannot be resized at runtime. So, to be able to
resize an array I have to create a new, larger one, and copy the existing
data. How do I do this?

Thanks,
Nigel
Thomas Maeder [TeamB]
2007-09-23 16:59:07 UTC
Permalink
Post by Nigel Mackay
I understand that arrays cannot be resized at runtime. So, to be
able to resize an array I have to create a new, larger one, and copy
the existing data. How do I do this?
The easiest way is using std::vector instead of an array.
macnab
2007-09-25 13:49:14 UTC
Permalink
Decided to use std::set. I have

typedef char MyStringType[30];
typedef struct
{
TDateTime When;
bool Alarm;
bool Cancelled;
MyStringType EventDescription;
} EventType;
EventType EventData;

template <class _Tp>
struct myless : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return
__x.When < __y.When; }
};
set <EventType, myless<EventType> > EventSet;

I fill EventData's fields and then
EventSet.insert(EventData);
Using EventSet.insert(EventData).second shows no insertion took place

What is wrong? I suspect __x.When < __y.When
macnab
2007-09-25 15:10:22 UTC
Permalink
Replaced
__x.When < __y.When
with
__x.EventDescription < __y.EventDescription

EventSet.insert(EventData).second now shows insertion took place. But
saving EventSet still has junk in the file, and still 32 bytes.
JD
2007-09-27 16:47:39 UTC
Permalink
Post by Thomas Maeder [TeamB]
Post by Nigel Mackay
I understand that arrays cannot be resized at runtime. So, to be
able to resize an array I have to create a new, larger one, and copy
the existing data. How do I do this?
The easiest way is using std::vector instead of an array.
Well ... this is the student group so I would have suggested
a dynamic array instead.

~ JD
macnab
2007-09-27 18:35:32 UTC
Permalink
Thanks, I didn't know that there were dynamic arrays. Makes sense,
otherwise the language would no be much use.
Now, how to stop the existing data being corrupted when increasing the
size of the array.

typedef struct
{
TDateTime When;
bool Alarm;
bool Cancelled;
MyStringType EventDescription;
} EventType;
EventType EventData;

DynamicArray<EventType> MyArray;

Then I set the values of EventData and...
NumEvents++;
MyArray.Length=NumEvents;
MyArray[NumEvents-1]=EventData;

Only the last entry is not corrupt.
macnab
2007-09-28 07:24:52 UTC
Permalink
Found my error
macnab
2007-09-28 08:25:27 UTC
Permalink
New problem!!!

If I create 1, 2 or 3 events and close the app, all the events are
saved (I check with a HexEditor and on opening app).
On app run to load old data I use

NumEvents=0;
EventSet.Length=0;

FileHandleI=open("EventData.dat",O_RDONLY);
if (FileHandleI != -1)
{
NumEvents=filelength(FileHandleI)/sizeof(EventType);
if (NumEvents > 0)
{
EventSet.Length=NumEvents;
for (x=0;x<NumEvents;x++)
{
read(FileHandleI,&EventData,sizeof(EventType));
EventSet[x]=EventData;
}
}
}
close(FileHandleI);

This loads all the saved events (I check them with Inspect)
If I close the app immediately, all events are saved again.
If I add an event,

NumEvents++;
EventSet.Length=NumEvents;
EventSet[NumEvents-1]=EventData;

then EventSet is the correct size and correct data, but closing the
app, which calls

if (NumEvents > 0)
{
FileHandleI=open("EventData.dat",O_CREAT+O_WRONLY);
for (x=0;x<NumEvents;x++)
{
write(FileHandleI,&EventSet[x],sizeof(EventType));
}
close(FileHandleI);
}

NumEvents is correct, the data in EventSet is correct, the routine
cycles the correct number of times through the loop, but it only saves
the old (loaded) data!!
Or put it this way, the hex editor shows only the original entries,
and running the app only loads the original entries. The file saving
routine is the same one, whether or not I add events.
Thorsten Kettner
2007-09-28 10:26:02 UTC
Permalink
Post by JD
Post by Thomas Maeder [TeamB]
The easiest way is using std::vector instead of an array.
Well ... this is the student group so I would have suggested
a dynamic array instead.
But std::vector _is_ the dynamic array in C++! What are you
referring to, JD? To DynamicArray? I wouldn't suggest that -
especially not in the students group - as it is VCL specific,
and I think they should focus on learning C++ rather than VCL.
macnab
2007-09-28 18:14:13 UTC
Permalink
I had a look at vector, set and deque. I had problems with all of
them.
My data is a structure, I need to be able to add and delete items, and
then write them to disk, and then load them again, and then add/
delete.
I am happy with adding to and removing from a DynamicArray, I have
experience with that from Visual Basic and Pascal.
I now have a problem with writing to and reading from the file.
To write I use

FileHandleI=open("EventData.dat",O_CREAT | O_RDWR | O_TRUNC |
O_BINARY);
y=errno;
for (x=0;x<NumEvents;x++)
{

BytesWritten=write(FileHandleI,&EventSet[x],sizeof(EventType));
y=errno;
}
close(FileHandleI);

If the file doesn't exist (first run) FileHandleI is 3, errno is 6
(bad file number) on opening the file, BytesWritten is correct and
errno is set to 7 (memory blocks destroyed).
If I check the file with a hex editor, it is correct.

To reopen the file I use

FileHandleI=open("EventData.dat",O_RDONLY);
y=errno;
if (FileHandleI!=-1)
{
NumEvents=filelength(FileHandleI)/sizeof(EventType);
if (NumEvents>0)
{
EventSet.Length=NumEvents;
for (x=0;x<NumEvents;x++)
{
read(FileHandleI,&EventData,sizeof(EventType));
y=errno;
EventSet[x]=EventData;
}
}
}
close(FileHandleI);

No error on open or read, data is correct.
However, now writing to the file (with or without adding data),
opening the file gives FileHandle -1 and errno 5 (permission denied).
If I try to use S_IWRITE and S_IWRITE (as the documentation suggests)
the compiler doesn't recognise them. Using Search, the only unit I can
find with them in is stats.h, but that is a refernce not a
declaration.
Until I get the file routines sorted, I am not going to get far with
the app.
macnab
2007-09-28 18:59:13 UTC
Permalink
Solved problem by reading documentatio carefully and including sys
\stat.
Further questions, if arising, will be asked under lang
unknown
2007-09-30 04:35:35 UTC
Permalink
Post by Thorsten Kettner
But std::vector _is_ the dynamic array in C++! What are you
referring to, JD? To DynamicArray?
I was.
Post by Thorsten Kettner
I wouldn't suggest that - especially not in the students
group - as it is VCL specific, and I think they should focus
on learning C++ rather than VCL.
This Borland and not M$!

In terms of suggesting a VCL solution over a pure C++ solution
using the std, I doubt that any respectable institution using
BCB would bypass the VCL in the first place (you need it for
the GUI after all!).

I just think that as a student, the std is beyond what's taught
and there is are so many concepts that need to be learned that
adding stuff from outside of the classroom is not conducive
to learning the particulare lesson.

However, after reconsidering, I should have suggested a double-
linked list which provides a solution to the problem and
illustrates the concept of being able to allocate on the fly
without reallocating and copying the entire array and it
bypasses the problem of memory fragmentation.

~ JD

Loading...