473,468 Members | 1,396 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Dynamic Structures

Hi,

Im new to C++ and trying to self teach myself whilst I sit at my
unentertaining day job (thought i'd put that across before im accused
of cheating on my homework, im 45...)

Anyway I'm trying to dynamically assign a structure whilst I read from
a file, however my program crashes, and im not sure why other than that
its to do with my memory operations using new and delete.

Im pretty good at C so the reason for learning is so that I can truely
put C/C++ on my CV instead of just C... but also im interested in the
object orrientated aspect.

Could I use a class instead of a structure? whats best? where am I
going wrong?

Thanks

Heres my Code -

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN
{
string linetoken;
};

int main()
{

TOKEN *Tokens;

int counter = 0;
ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{

Tokens = new TOKEN[counter + 1];

Tokens[counter].linetoken = line;

//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";

delete Tokens;
return 0;
}

Aug 29 '06 #1
12 3040
<go*************@hotmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
Anyway I'm trying to dynamically assign a structure whilst I read from
a file, however my program crashes,
How far does it get before crashing? Does it display "AAAAAA" first?
and im not sure why other than that
its to do with my memory operations using new and delete.

Could I use a class instead of a structure? whats best? where am I
going wrong?
Anything you can do with a class you can do with a structure, and vice
versa. The difference is the default visibility (private for class, public
for struct).
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN
I wouldn't have made that uppercase. (But your style != my style.)
{
string linetoken;
};

int main()
{

TOKEN *Tokens;

int counter = 0;
ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{

Tokens = new TOKEN[counter + 1];
new[] is analogous to malloc(), not to realloc(). You're leaking memory each
time through this loop beyond the first, because you lose the memory Tokens
used to point at.

This is why in C++ container classes are usually used instead. It'd be much
easier to use a std::vector<TOKENhere, then you could just do
token.push_back(TOKEN(counter + 1)); each time round the loop and not have
to worry about memory allocation.

On the other hand, if you are doing this as an excercise for yourself in
dynamic memory management, perhaps you should create your own container
class. Call it something like TokenContainer, TokenList or TokenArray and
provide a method to add a new token on the end, and another to get values
from it. You can implement it as a resizable array, or as a linked list, or
in any other way you like. Focus on correctness over speed. Make sure your
destructor deletes everything in the container cleanly. Use a memory leak
detector (such as valgrind) to check if you really did delete everything.

Once you have created your TokenContainer and got it working, throw it away
and use std::vector, std::deque or std::list. They're likely to be much more
stable and much faster than your container :)
Tokens[counter].linetoken = line;

//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";

delete Tokens;
Wrong operator. This should be:
delete[] Tokens;
since you used new to create an array instead of a single object. This is
possibly the cause of the crash.
return 0;
}
Aug 29 '06 #2
<go*************@hotmail.comschrieb im Newsbeitrag
news:11**********************@m73g2000cwd.googlegr oups.com...
Hi,

Im new to C++ and trying to self teach myself whilst I sit at my
unentertaining day job (thought i'd put that across before im accused
of cheating on my homework, im 45...)

Anyway I'm trying to dynamically assign a structure whilst I read from
a file, however my program crashes, and im not sure why other than that
its to do with my memory operations using new and delete.

Im pretty good at C so the reason for learning is so that I can truely
put C/C++ on my CV instead of just C... but also im interested in the
object orrientated aspect.

Could I use a class instead of a structure? whats best? where am I
going wrong?

Thanks

Heres my Code -

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN
Don't use identifiers with upper-case letters only. Those names should
better be reserved for identifiers used for #define'd macros.
{
string linetoken;
};

int main()
{

TOKEN *Tokens;
You should always initialize your variables, especially pointers.
int counter = 0;
Why do you write Tokens with an upper-case T but counter with a lower-case
c? Try to find a consistent naming convention. It makes life a lot easier if
you don't have to remember which name to start with an upper-case letter
andwhich one with a lower-case letter.
ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{

Tokens = new TOKEN[counter + 1];
This creates an array of counter+1 TOKENs and assigns the address of the
first element in the array to Tokens. Initially it allocates an array with
just one element and assigns its address to Tokens, overwritting Tokens's
undefined value. Nothing wrong so far.

On the next run, it allocates a NEW array with 2 elements and assigns the
address of the first element to Tokens, overwriting the old value of Tokens,
the array allocated during the previous pass through the loop. That results
in a memory leak, one in every round through the loop, except for the first
one.
Tokens[counter].linetoken = line;
This stores the contents of line in the last element of the newly allocated
array. All other elements of the array will contain default values, empty
strings in this case.
//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";

delete Tokens;
This causes undefined behaviour. You must only delete something you got from
new. If you used new[] to allocate memory, you have to use delete[] to free
it again.
return 0;
}
You have to allocate one array large enough to hold all the lines in
advance. Just because you allocate larger ones in each loop and assign their
address to the same variable, does not copy the contents of the previous
array to the new one. If you find out, that your array isn't large enough,
you have to create a new, larger one, copy all existing data from the old
array to the new one and finally delete[] the old array before you overwrite
its address with that of the new array.

Or you better learn about containes like std::list or std::vector. They are
much easier to use then C style arrays allocated with new[]/delete[].
Compare this with your code:

int main()
{
std::vector<TOKENtokens;
std::ifstream ifs("data.txt");
std::string line;
while (std::getline(ifs, line))
{
tokens.push_back(line);
std::cout << tokens.back().linetoken << std::endl;
}
std::cout << tokens.size() << " lines read" << std::endl;
}

HTH
Heinz

Aug 29 '06 #3
go*************@hotmail.com wrote:
Heres my Code -

#include <iostream>
#include <fstream>
#include <string>
I recommend to also include <ostream>, because you use "endl" later in your
code. Including <iostreamand/or <fstreamdoes not guarantee to make endl
available. Or, instead of using endl to display a newline you could just
output '\n', if you do not need to flush the output at the same time.
Aug 29 '06 #4

<go*************@hotmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
Hi,

Im new to C++ and trying to self teach myself whilst I sit at my
unentertaining day job (thought i'd put that across before im accused
of cheating on my homework, im 45...)

Anyway I'm trying to dynamically assign a structure whilst I read from
a file, however my program crashes, and im not sure why other than that
its to do with my memory operations using new and delete.

Im pretty good at C so the reason for learning is so that I can truely
put C/C++ on my CV instead of just C... but also im interested in the
object orrientated aspect.

Could I use a class instead of a structure? whats best? where am I
going wrong?

Thanks

Heres my Code -

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN
{
string linetoken;
};

int main()
{

TOKEN *Tokens;

int counter = 0;
ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{

Tokens = new TOKEN[counter + 1];

Tokens[counter].linetoken = line;

//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";

delete Tokens;
return 0;
}
This is not the way I would design this. But...

You have a TOKEN pointer. I presume at the end you want to have this Token
pointer contain a dynamic array of all the tokens (lines in the file).

What you are doing:

while ( data exists )
read line.
Allocate array of tokens with number of lines so far
assign last element to current line
Delete array.

The problem with this is you loose the previous data in a memory leak.
There are much better algorithms, but you could make yours work if you did
this:

while ( data exists )
read line
allocate array of tokens with number of lines so far
copy all the old strings into the array
delete old array
assign last telement to current line
delete array

Note: The following is untested code, but should give you the idea.
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct TOKEN
{
string linetoken;
};

int main()
{

TOKEN *Tokens;

int counter = 0;
ifstream ifs("data.txt");
string line;

while(getline(ifs,line))
{
// Save pointer to aready allocated tokens
TOKEN* LastTokens = Tokens;
Tokens = new TOKEN[counter + 1];
// Note, this only works if counter == 0 because even though Tokens hasn't
been allocated
// yet, we actually don't do anything for an empty array because 0 < 0 evals
false on
// first run though.
// std::copy could also be used I believe
for ( int i = 0; i < counter; ++i )
Tokens[i] = LastTokens[i];
delete[] LastTokens;
>
Tokens[counter].linetoken = line;

//cout << "[ " << line << " ]" << endl;
cout << Tokens[counter].linetoken << endl;
counter = counter + 1;
}

cout << "AAAAAAAA";
// At this point, Tokens points to a dynamically allocated array of Tokens
containing all the lines in the file.
>
delete Tokens;
change this to
delete Tokens[];
return 0;
}
This is a rather ineffecient way to do this, because for n elements you have
n memory allocations and !n copies. A container such as vector does
something similar but it will allocate the previous allocated space *2 each
time so memory allocations and copies are only done when memory allocation
takes place. Of course this means the container has to keep track of how
much memory is allocated for how many elements and how many elements
actually have data in them.
Aug 29 '06 #5
Heinz Ozwirk wrote:
>struct TOKEN

Don't use identifiers with upper-case letters only. Those names should
better be reserved for identifiers used for #define'd macros.
Oh posh. This is C++, not decade old C. Macros are rarely used.
>
Aug 29 '06 #6
Ron Natalie posted:
>>struct TOKEN

Don't use identifiers with upper-case letters only. Those names should
better be reserved for identifiers used for #define'd macros.

Oh posh. This is C++, not decade old C. Macros are rarely used.

Heinz gave very good advice -- reserve the use of ALL-UPPERCASE for macro
names only (regardless of how frequently or rarely you use them).

--

Frederick Gotham
Aug 29 '06 #7
Frederick Gotham wrote:
Heinz gave very good advice -- reserve the use of ALL-UPPERCASE for macro
names only (regardless of how frequently or rarely you use them).
Let's hope he was joking.

Jens

Aug 29 '06 #8
Jens Theisen wrote:
Frederick Gotham wrote:
>Heinz gave very good advice -- reserve the use of ALL-UPPERCASE for
macro names only (regardless of how frequently or rarely you use
them).

Let's hope he was joking.
Why? It's a good style advice. Makes macros visible. They have their
special traits and often need to be easily identifialbe throughout the
code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 29 '06 #9
Victor Bazarov wrote:
Why? It's a good style advice. Makes macros visible. They have their
special traits and often need to be easily identifialbe throughout the
code.
Sorry if it wasn't clear, but I was referring to
Oh posh. This is C++, not decade old C. Macros are rarely used
which probably was a joke.

Jens
Aug 29 '06 #10
Victor Bazarov wrote:
Jens Theisen wrote:
>Frederick Gotham wrote:
>>Heinz gave very good advice -- reserve the use of ALL-UPPERCASE for
macro names only (regardless of how frequently or rarely you use
them).
Let's hope he was joking.

Why? It's a good style advice. Makes macros visible. They have their
special traits and often need to be easily identifialbe throughout the
code.
It's antiquated style advice and has never been held to even by the
language/libraries itself (FILE isn't a macro, and assert is, for
example).

A better advice would be to avoid preprocessor macros if possible
in C++. If you do that, there's no point in wasting a whole class
of variable names on something you never do.

Aug 29 '06 #11
Ron Natalie wrote:
Victor Bazarov wrote:
>Jens Theisen wrote:
>>Frederick Gotham wrote:
Heinz gave very good advice -- reserve the use of ALL-UPPERCASE for
macro names only (regardless of how frequently or rarely you use
them).
Let's hope he was joking.

Why? It's a good style advice. Makes macros visible. They have
their special traits and often need to be easily identifialbe
throughout the code.

It's antiquated style advice and has never been held to even by the
language/libraries itself (FILE isn't a macro, and assert is, for
example).
Yes, but you know them, I know them, many others know them, so it's not
such a big deal to have a couple of exceptions to the rule.
A better advice would be to avoid preprocessor macros if possible
in C++. If you do that, there's no point in wasting a whole class
of variable names on something you never do.
Yes, as an orthogonal rule, the macros should be avoided. If/when they
cannot be, making their names uppercase is preferred.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 29 '06 #12
Jens Theisen wrote:
Victor Bazarov wrote:
>Why? It's a good style advice. Makes macros visible. They have
their special traits and often need to be easily identifialbe
throughout the code.

Sorry if it wasn't clear, but I was referring to
>Oh posh. This is C++, not decade old C. Macros are rarely used

which probably was a joke.
Ah...
Aug 29 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Charlie | last post by:
Hi, The description of Python always mentions "very high level dynamic data types". Now, I can't seem to find any examples of these (nothing described with this term anyway). Is this simply...
12
by: CJM | last post by:
How can I dynamically sort the results from a Stored Procedure? Or more importantly, what is the fastest and most efficient way? I know I can do the sorting within the recordset in ASP, but AFAIK...
8
by: Peter B. Steiger | last post by:
The latest project in my ongoing quest to evolve my brain from Pascal to C is a simple word game that involves stringing together random lists of words. In the Pascal version the whole array was...
5
by: RBCC | last post by:
Does anyone know how to dynamically allocate array of structures? Or where Ican find info on this on the web? John
13
by: Krivenok Dmitry | last post by:
Hello all! Perhaps the most important feature of dynamic polymorphism is ability to handle heterogeneous collections of objects. ("C++ Templates: The Complete Guide" by David Vandevoorde and...
5
by: Daniel Frey | last post by:
Hello I'd like to match a dynamic node, given as a parameter to the stylesheet. Something like: <xsl:stylesheet ...> <xsl:param name="tomatch"/> <xsl:template match="{$tomatch}"> Hallo...
24
by: Ken | last post by:
In C programming, I want to know in what situations we should use static memory allocation instead of dynamic memory allocation. My understanding is that static memory allocation like using array...
1
by: Gurur | last post by:
Hi all, I have a doubt. If I have 2 structures and one is parent of other , ie the child structure is present in the parent one . And if the child structure is declared as dynamic array in the...
4
by: stallone3 | last post by:
Hi, My question is more of a perfomance or common practice doubt about dynamic structures usage: I have a function that will be called to search a file for a certain condition in particular...
5
by: bearophileHUGS | last post by:
I often use Python to write small programs, in the range of 50-500 lines of code. For example to process some bioinformatics data, perform some data munging, to apply a randomized optimization...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.