Hello,

I am learning to use Borland Builder 6.0 (and trying to remember/learn to use C++ after taking a college course in C programming nine years ago). I have created a data structure. When I try to delete it using:

delete films;

I am told that deleting an object requires exactly one conversion to pointer...

I wish I knew what this means. More fundamentally, I wish I knew how to modify the following structure definition in a manner that will permit me to delete it (and thus serve as a guide in the future).

struct movies
{
char title[10];
int year;
};
movies films;

Please accept my thanks in advance for any assistance that you provide.

Exactly 1 delete for every new?

struct movies
{
   char title[10];
   int year;
};

int main()
{
   movies *films = new movies;
   // use films
   delete films;
   return 0;
}

Or don't use delete and don't use new?

struct movies
{
   char title[10];
   int year;
};

int main()
{
   movies films;
   // use films
   return 0;
}

code tags : [code][/code]

Thank you for the response.

I realize that not using "delete" in reference to the structure does eliminate the problem, but had hoped to learn how to free up memory that might otherwise be used by large structures in the manner usually deemed to be correct in programming circles. I did attempt:

struct movies
{
char title[10];
int year;
};
int main()
{
movies *films = new movies;
// use films
movies.title = "Harts War";
delete films;
return 0;
}

The compiler responds with an error on the line that tries to assign a string to the title. I believe it is complaining about a pointer being on one side but no pointer on the other. If anyone can provide a means of both creating a structure and using its components, so that I can learn how to delete a structure in Builder 6.0 if I wish, I would be very grateful.

Thank you.

but had hoped to learn how to free up memory that might otherwise be used by large structures in the manner usually deemed to be correct in programming circles

Automatic memory is freed when an object goes out of scope.

<Fixed code tags: [code][/code].>

struct movies
{
   char title[10];
   int year;
};

int main()
{
   movies *films = new movies;
   // use films
   movies.title = "Harts War";
   delete films;
   return 0;
}

The compiler responds with an error on the line that tries to assign a string to the title. I believe it is complaining about a pointer being on one side but no pointer on the other.

First, movies is a type, not an object. So this

movies.title = "Harts War";

should be this

films->title = "Harts War";

But that is still wrong because you cannot assign C-style strings that way. Use strcpy or std::string for assignment.

If anyone can provide a means of both creating a structure and using its components, so that I can learn how to delete a structure in Builder 6.0 if I wish, I would be very grateful.

What is the bigger picture? What do you want to do? (Don't solve the wrong problem with a perceived solution.)

Automatic memory is freed when an object goes out of scope.

First, movies is a type, not an object. So this

movies.title = "Harts War";

should be this

films->title = "Harts War";

But that is still wrong because you cannot assign C-style strings that way. Use strcpy or std::string for assignment.

What is the bigger picture? What do you want to do? (Don't solve the wrong problem with a perceived solution.)

-------------------------------------------------------------

THANK YOU. I am now able to create and delete a structure. As for the bigger picture, I had the functions working before I submitted my first post to this forum. I had perceived the deletion of a structure as a mere detail...until now. The reason follows and is based upon differences in the way in which one must code to use the structure after declaring it using a pointer reference.

When I created the structure using "movies films;", and referenced the data using "films.title" and "films.year", my file input/output (read/write to disk) functions worked well. When I create the structure using "movies *films = new movies;", and reference the contents using "films->title" and "films->year", I can no longer display the title. What is the difference between these two approaches, and why must I use two different means of referencing the variables that comprise the structure depending on how the structure is declared?

I am saving and reading structures from files using an iostream function and am referencing the structure to be saved using a char pointer as "(char*)(&films)". The problem seems to arise if I use the pointer means of declaring the structure ("movies *films = new movies;") when I read from the file and try to display "films->title" in a RichEdit text control using "RichEdit2->Text = films->title". I had this problem previously when I declared "title" to be an AnsiString, but worked through it and used char[10] to declare "title", StrCopy() to load data into "films.title", and "RichEdit2->Text = films.title" to display it.

(Just a note, in that the use of movies instead of films in the variable assignment in my prior post was not a conceptual error, I typed the wrong variable name in the post. (They sound similar, and I didn't have the code in front of me). I had worked through the StrCopy() problem last night when I first encountered it, but had forgotten how to handle it this morning when the error arose again after I had retyped a segment of code with the new declaration statement. I probably would have continued to struggle had the prior post not reminded me of the manner of solution of that problem.)

I am most certainly not trying to diminish the value of the assistance I have received here, and am both surprised by and grateful for the speed of the responses I have received.

I had hoped to create a general structure I/O function for my future use, but now seem to need to create two differently coded structure I/O functions to accomodate the pointer means of declaring the structure, particularly if I wish to comply with the current C++ ANSI standard in my coding efforts in terms of the means by which I declare a structure. Using the iostream method, a pointer to a location in memory, and the size of the data I need to store, doesn't seem to enable me to display the title using "RichEdit2->Text = films->title;". I had previously been able to load the title as part of the structure that was loaded using the iostream method, then used "RichEdit2->Text = films.title" to display the title when I declared the structure using "movies films;".

Once again, and most sincerely, thank you!

As for the bigger picture, I had the functions working before I submitted my first post to this forum. I had perceived the deletion of a structure as a mere detail...until now. The reason follows and is based upon differences in the way in which one must code to use the structure after declaring it using a pointer reference.

What I meant by the bigger picture was, "This program reads and writes movie information from/to a text file. Movie information is then displayed ..." The minutae are the details of structures, dynamic/automatic allocation, etc.

For example, loading a particular structure with information: why do you need dynamic allocation? Is the structure several thousand bytes in size? Is it part of a linked list? If the information is relatively small and the data is displayed (and discarded) as it is being read, then why bother?

When I created the structure using "movies films;", and referenced the data using "films.title" and "films.year", my file input/output (read/write to disk) functions worked well. When I create the structure using "movies *films = new movies;", and reference the contents using "films->title" and "films->year", I can no longer display the title. What is the difference between these two approaches, and why must I use two different means of referencing the variables that comprise the structure depending on how the structure is declared?

Are you asking about the difference between accessing structure members with the . and the -> operator? You use . with objects and -> with pointers to objects.

I am saving and reading structures from files using an iostream function and am referencing the structure to be saved using a char pointer as "(char*)(&films)". The problem seems to arise if I use the pointer means of declaring the structure ("movies *films = new movies;") when I read from the file and try to display "films->title" in a RichEdit text control using "RichEdit2->Text = films->title". I had this problem previously when I declared "title" to be an AnsiString, but worked through it and used char[10] to declare "title", StrCopy() to load data into "films.title", and "RichEdit2->Text = films.title" to display it.

As I mentioned, this is not really what I was getting at with the 'big picture'. If you are going into such detail, you might as well post the code. Paraphrasing code leads to debugging paraphrasing, which may be neither here nor there.

I had hoped to create a general structure I/O function for my future use, but now seem to need to create two differently coded structure I/O functions to accomodate the pointer means of declaring the structure, particularly if I wish to comply with the current C++ ANSI standard in my coding efforts in terms of the means by which I declare a structure. Using the iostream method, a pointer to a location in memory, and the size of the data I need to store, doesn't seem to enable me to display the title using "RichEdit2->Text = films->title;". I had previously been able to load the title as part of the structure that was loaded using the iostream method, then used "RichEdit2->Text = films.title" to display the title when I declared the structure using "movies films;".

Again, I think you may need to try to see the forest from the trees (or at least help me do so).

For example, the following is a short snippet that uses a couple of functions that do very much the same thing in two different ways. The mywrite function uses dynamic allocation, the myread function uses automatic allocation. Both essentially do the same thing, but mywrite has excess overhead for the (in my opinion needless) dynamic allocation.

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

struct movie
{
   char title[30];
   int  year;
};

movie collection[] =
{
   { "Star Wars",           1978},
   { "Empire Strikes Back", 1980},
   { "Return of the Jedi",  1983},
};

void mywrite(const char *filename)
{
   ofstream file(filename);
   movie *film = new movie;
   for ( size_t i = 0; i < sizeof collection / sizeof *collection; ++i )
   {
      strcpy(film->title, collection[i].title);
      film->year = collection[i].year;
      file << film->title << ',' << film->year << '\n';
   }
   delete film;
}

void myread(const char *filename)
{
   ifstream file(filename);
   movie film;
   while ( file.getline(film.title, sizeof film.title, ',') &&
           file >> film.year && file.get() )
   {
      cout << film.title << ',' << film.year << '\n';
   }
}

int main()
{
   const char filename[] = "file.txt";
   mywrite(filename);
   myread(filename);
   return 0;
}

/* my output
Star Wars,1978
Empire Strikes Back,1980
Return of the Jedi,1983
*/

What I meant by the bigger picture was, "This program reads and writes movie information from/to a text file. Movie information is then displayed ..." The minutae are the details of structures, dynamic/automatic allocation, etc.

For example, loading a particular structure with information: why do you need dynamic allocation? Is the structure several thousand bytes in size? Is it part of a linked list? If the information is relatively small and the data is displayed (and discarded) as it is being read, then why bother?

Are you asking about the difference between accessing structure members with the . and the -> operator? You use . with objects and -> with pointers to objects.

As I mentioned, this is not really what I was getting at with the 'big picture'. If you are going into such detail, you might as well post the code. Paraphrasing code leads to debugging paraphrasing, which may be neither here nor there.

Again, I think you may need to try to see the forest from the trees (or at least help me do so).

For example, the following is a short snippet that uses a couple of functions that do very much the same thing in two different ways. The mywrite function uses dynamic allocation, the myread function uses automatic allocation. Both essentially do the same thing, but mywrite has excess overhead for the (in my opinion needless) dynamic allocation.

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

struct movie
{
   char title[30];
   int  year;
};

movie collection[] =
{
   { "Star Wars",           1978},
   { "Empire Strikes Back", 1980},
   { "Return of the Jedi",  1983},
};

void mywrite(const char *filename)
{
   ofstream file(filename);
   movie *film = new movie;
   for ( size_t i = 0; i < sizeof collection / sizeof *collection; ++i )
   {
      strcpy(film->title, collection[i].title);
      film->year = collection[i].year;
      file << film->title << ',' << film->year << '\n';
   }
   delete film;
}

void myread(const char *filename)
{
   ifstream file(filename);
   movie film;
   while ( file.getline(film.title, sizeof film.title, ',') &&
           file >> film.year && file.get() )
   {
      cout << film.title << ',' << film.year << '\n';
   }
}

int main()
{
   const char filename[] = "file.txt";
   mywrite(filename);
   myread(filename);
   return 0;
}

/* my output
Star Wars,1978
Empire Strikes Back,1980
Return of the Jedi,1983
*/

----------------------------------------------


Many thanks to Mr. Sinkula for all of his assistance with this thread. The content provides valuable insight into the difference between stack based objects and dynamically allocated (heap associated) structures, as well as identifying variations in application between pointers and objects. I have, at this time, developed the functions that meet my goals in that they are now consistent with the C++ ANSI standard methods for creating and deleting structures contained within Builder 6.0. I couldn't have done it without the assistance that I have received at this site.

This article has been dead for over six months. Start a new discussion instead.