473,411 Members | 2,014 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,411 software developers and data experts.

destroying objects

This program simply reads a list of employes from the user, prints it
and then destroys the allocated memory. I have a function
free_memory(void *ptr) which will free the memory pointed to by
pointer ptr. I included a pointer to this function in the emplist
data structure free_employee_list. Is this a good way to program ??
what if there are a number of such different data structures. Would it
suffice to have a single free_memory function throughout the project
and include a pointer to this function in every data structure ??

#include <stdio.h>
#include <stdlib.h>

typedef struct _employee
{
int eid;
float sal;
int age;
}employee;

typedef struct _emplist
{
int n;
employee *e;
void (*free_employee_list)();
}emplist;
void free_memory(void *ptr)
{
free(ptr);
printf("\nMemory freed\n");
}
int main(void)
{
emplist *list;
int i;

list = malloc(sizeof(*list));
if(list == NULL)
{
fprintf(stderr, "memory allocation failed\n");
return 1;
}

list->free_employee_list = free_memory;
printf("Enter number of employees\n");
scanf("%d", &list->n);

list->e = malloc(sizeof(employee) * list->n);

if(list->e == NULL)
{
fprintf(stderr, "memory allocation failed\n");
return 1;
}

for(i = 0; i < list->n; i++)
{
printf("Enter id, age, salary\n");
scanf("%d %d %f", &list->e[i].eid, &list->e[i].age, &list-
>e[i].sal);
}

for(i = 0; i < list->n; i++)
{
printf("Employe id: %d age: %d sal: %f\n", list->e[i].eid, list-
>e[i].age, list->e[i].sal);
}

list->free_employee_list(list);

return 0;
}
Jun 27 '08 #1
14 1546

"pereges" <Br*****@gmail.comwrote in message news:
This program simply reads a list of employes from the user, prints it
and then destroys the allocated memory. I have a function
free_memory(void *ptr) which will free the memory pointed to by
pointer ptr. I included a pointer to this function in the emplist
data structure free_employee_list. Is this a good way to program ??
It's (arguably) a good way to program, but not in C. C's syntax isn't rich
enough to support a heavily indirected set of function pointers embedded in
their own structures. It's an easy route to unreadability.

However the same idea in C++ is fine. The language will call destructors
automatically for you.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jun 27 '08 #2
pereges wrote:
This program simply reads a list of employes from the user, prints it
and then destroys the allocated memory. I have a function
free_memory(void *ptr) which will free the memory pointed to by
pointer ptr. I included a pointer to this function in the emplist
data structure free_employee_list. Is this a good way to program ??
what if there are a number of such different data structures. Would it
suffice to have a single free_memory function throughout the project
and include a pointer to this function in every data structure ??

#include <stdio.h>
#include <stdlib.h>

typedef struct _employee
{
int eid;
float sal;
int age;
}employee;

typedef struct _emplist
{
int n;
employee *e;
void (*free_employee_list)();
}emplist;
void free_memory(void *ptr)
{
free(ptr);
printf("\nMemory freed\n");
}
int main(void)
{
emplist *list;
int i;

list = malloc(sizeof(*list));
if(list == NULL)
{
fprintf(stderr, "memory allocation failed\n");
return 1;
}

list->free_employee_list = free_memory;
printf("Enter number of employees\n");
scanf("%d", &list->n);

list->e = malloc(sizeof(employee) * list->n);

if(list->e == NULL)
{
fprintf(stderr, "memory allocation failed\n");
return 1;
}

for(i = 0; i < list->n; i++)
{
printf("Enter id, age, salary\n");
scanf("%d %d %f", &list->e[i].eid, &list->e[i].age, &list-
>e[i].sal);
}

for(i = 0; i < list->n; i++)
{
printf("Employe id: %d age: %d sal: %f\n", list->e[i].eid, list-
>e[i].age, list->e[i].sal);
}

list->free_employee_list(list);

return 0;
}
It looks overly complicated to me.
I don't understand why it isn't just as simple
as allocating an array of structures and then freeing it.

/* BEGIN employees_2.c */

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
struct {
int eid;
double sal;
int age;
} *e_ptr;
unsigned i, n;

puts("/* BEGIN employees_2.c output */\n");
puts("Enter number of employees");
if (scanf("%u", &n) != 1) {
puts("Forget about it.");
exit(EXIT_SUCCESS);
}
e_ptr = malloc(n * sizeof *e_ptr);
if (e_ptr == NULL) {
puts("e_ptr == NULL");
exit(EXIT_FAILURE);
}

for (i = 0; i != n; ++i) {
puts("Enter id, age, salary");
if (scanf("%d %d %lf",
&e_ptr[i].eid,
&e_ptr[i].age,
&e_ptr[i].sal) != 3)
{
puts("Forget about it.");
break;
}
}
putchar('\n');
for (n = 0; i != n; ++n) {
printf("Employe id: %d age: %d sal: %f\n",
e_ptr[n].eid,
e_ptr[n].age,
e_ptr[n].sal);
}
free(e_ptr);
puts("\nArray is freed.\n");
puts("/* END employees_2.c output */");
return 0;
}

/* END employees_2.c */
--
pete
Jun 27 '08 #3
On Wed, 11 Jun 2008 11:11:24 -0700 (PDT), pereges <Br*****@gmail.com>
wrote:
>This program simply reads a list of employes from the user, prints it
and then destroys the allocated memory. I have a function
free_memory(void *ptr) which will free the memory pointed to by
pointer ptr. I included a pointer to this function in the emplist
data structure free_employee_list. Is this a good way to program ??
Is it a good idea to have a function whose only purpose is to call a
standard function? I think not.

Is it a good idea to have a function pointer point to this function?
Not unless you have more than one such function and the point where
you decide which one to use is removed from the point where you call
the function.

Is it a good idea to have this pointer as a member of the struct
_emplist? Probably, since everything else you need to "control"
struct _employee is included in struct _emplist.
>what if there are a number of such different data structures. Would it
suffice to have a single free_memory function throughout the project
and include a pointer to this function in every data structure ??
If you only have one function, why bother wasting the space for a
pointer to it in every data structure.
>
#include <stdio.h>
#include <stdlib.h>

typedef struct _employee
{
int eid;
float sal;
int age;
}employee;

typedef struct _emplist
{
int n;
employee *e;
void (*free_employee_list)();
}emplist;
void free_memory(void *ptr)
{
free(ptr);
printf("\nMemory freed\n");
It would be nice if you said what memory was being freed. Something
like
printf("\nMemory allocated at %p freed\n", ptr);
free(ptr);
>}
int main(void)
{
emplist *list;
int i;

list = malloc(sizeof(*list));
if(list == NULL)
{
fprintf(stderr, "memory allocation failed\n");
It would be nice to indicate which allocation failed.
return 1;
To be portable use EXIT_FAILURE.
}

list->free_employee_list = free_memory;
printf("Enter number of employees\n");
scanf("%d", &list->n);

list->e = malloc(sizeof(employee) * list->n);

if(list->e == NULL)
{
fprintf(stderr, "memory allocation failed\n");
You ought to free list at this point.
return 1;
}

for(i = 0; i < list->n; i++)
{
printf("Enter id, age, salary\n");
scanf("%d %d %f", &list->e[i].eid, &list->e[i].age, &list-
>>e[i].sal);
}

for(i = 0; i < list->n; i++)
{
printf("Employe id: %d age: %d sal: %f\n", list->e[i].eid, list-
>>e[i].age, list->e[i].sal);
}

list->free_employee_list(list);
By not freeing list->e before freeing list, you have created a memory
leak.
>
return 0;
}

Remove del for email
Jun 27 '08 #4
On 11 Jun, 19:11, pereges <Brol...@gmail.comwrote:

I agree with the other posters

<snip>
typedef struct _employee
identifiers beginning with _ are in the reserved namespace.
That is only compiler writters and standard library implementors
should use it. (The rules are slightly more complicated but
"don't begin identifiers with underscore" is easy to remember).

<snip>
* printf("Enter number of employees\n");
* scanf("%d", &list->n);

* list->e = malloc(sizeof(employee) * list->n);
failure to test return value of scanf(). scanf() is tricky to use,
its error recovery is poor (try entering a string of letters).
Use fgets() and fscanf().

<snip>
--
Nick Keighley

The fscanf equivalent of fgets is so simple
that it can be used inline whenever needed:-
char s[NN + 1] = "", c;
int rc = fscanf(fp, "%NN[^\n]%1[\n]", s, &c);
if (rc == 1) fscanf("%*[^\n]%*c);
if (rc == 0) getc(fp);

(actually it can't be *that* simple as I've just spotted two syntax
errors...)
Jun 27 '08 #5
"Nick Keighley" <ni******************@hotmail.comwrote in message
news:3c**********************************@x41g2000 hsb.googlegroups.com...
On 11 Jun, 19:11, pereges <Brol...@gmail.comwrote:
I agree with the other posters
<snip>
typedef struct _employee
identifiers beginning with _ are in the reserved namespace.
That is only compiler writters and standard library implementors
should use it. (The rules are slightly more complicated but
"don't begin identifiers with underscore" is easy to remember).
Something like the following is perfectly fine:
_________________________________________________
#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}

int main(void) {
foo(1);
getchar();
return 0;
}

_________________________________________________

http://groups.google.com/group/comp....5f62667b250ca3
[...]

Jun 27 '08 #6
Chris Thomasson wrote:
"Nick Keighley" <ni******************@hotmail.comwrote:
>pereges <Brol...@gmail.comwrote:
.... snip ...
>>
>>typedef struct _employee

identifiers beginning with _ are in the reserved namespace.
That is only compiler writters and standard library implementors
should use it. (The rules are slightly more complicated but
"don't begin identifiers with underscore" is easy to remember).

Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}

int main(void) {
foo(1);
getchar();
return 0;
}
Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #7
"CBFalconer" <cb********@yahoo.comwrote in message
news:48***************@yahoo.com...
Chris Thomasson wrote:
>"Nick Keighley" <ni******************@hotmail.comwrote:
>>pereges <Brol...@gmail.comwrote:
... snip ...
>>>
typedef struct _employee

identifiers beginning with _ are in the reserved namespace.
That is only compiler writters and standard library implementors
should use it. (The rules are slightly more complicated but
"don't begin identifiers with underscore" is easy to remember).

Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}

int main(void) {
foo(1);
getchar();
return 0;
}

Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.
Ouch. Well, I thought that identifiers which start with a double underscore,
single underscore followed by a uppercase character, or a single underscore
at file scope are not allowed. Since function parameters are not at file
scope, well, using `_this' should be fine. Where am I going wrong?

Thanks.

Jun 27 '08 #8
"CBFalconer" <cb********@yahoo.comwrote in message
news:48***************@yahoo.com...
Chris Thomasson wrote:
>"Nick Keighley" <ni******************@hotmail.comwrote:
>>pereges <Brol...@gmail.comwrote:
... snip ...
>>>
typedef struct _employee

identifiers beginning with _ are in the reserved namespace.
That is only compiler writters and standard library implementors
should use it. (The rules are slightly more complicated but
"don't begin identifiers with underscore" is easy to remember).

Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}

int main(void) {
foo(1);
getchar();
return 0;
}

Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.
I agree that using `this' would be a heck of a lot safer. Its been a nasty
habit of mine to use `_this'.

;^(...

Jun 27 '08 #9
CBFalconer <cb********@yahoo.comwrites:
Chris Thomasson wrote:
>"Nick Keighley" <ni******************@hotmail.comwrote:
>>pereges <Brol...@gmail.comwrote:
... snip ...
>>>
typedef struct _employee

identifiers beginning with _ are in the reserved namespace.
That is only compiler writters and standard library implementors
should use it. (The rules are slightly more complicated but
"don't begin identifiers with underscore" is easy to remember).

Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}

int main(void) {
foo(1);
getchar();
return 0;
}

Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.
stdio.h cannot legally define a macro named "_this". As Nick wrote
above, the rules are "slightly more complicated". Specifically (C99
7.1.3):

Identifiers beginning with an underscore and an uppercase letter,
or with two underscores, are always reserved for any use. For
example, stdio.h could define a macro "__this" or "_This".

Identifiers beginning with an underscore are reserved for use as
identifiers with file scope. For example, stdio.h could declare a
function "_this".

But since "_this" in Chris's code is not at file scope, it doesn't
violate one of the standard's reservations.

The above program is perfectly legal, and in fact it's arguably
strictly conforming (ignoring the possibility of printf failing).

However, I wouldn't call it "perfectly fine" on stylistic grounds.
First, I prefer to avoid declaring identifiers starting with
underscores altogether, since it's easier than keeping track of the
distinction between the two cases I cited above (and expecting anyone
reading the code to do so as well). It's not as if avoiding leading
underscores places a burdensome limitation on the set of identifiers I
can use.

Second, the ``getchar()'' call is superfluous; all it does is silently
wait for user input before terminating the program, which is just
annoying. (Yes, there are systems where this is useful, but there are
other ways to achieve the same effect.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #10
Chris Thomasson wrote:
"CBFalconer" <cb********@yahoo.comwrote in message
>Chris Thomasson wrote:
.... snip ...
>>
>>Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}

int main(void) {
foo(1);
getchar();
return 0;
}

Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.

Ouch. Well, I thought that identifiers which start with a double
underscore, single underscore followed by a uppercase character, or
a single underscore at file scope are not allowed. Since function
parameters are not at file scope, well, using `_this' should be
fine. Where am I going wrong?
When macros are expanded the system has not parsed the function
header. It is just so much more text to be treated according to
the macro rules.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #11
CBFalconer <cb********@yahoo.comwrites:
Chris Thomasson wrote:
>"CBFalconer" <cb********@yahoo.comwrote in message
>>Chris Thomasson wrote:
... snip ...
>>>
Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}

int main(void) {
foo(1);
getchar();
return 0;
}

Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.

Ouch. Well, I thought that identifiers which start with a double
underscore, single underscore followed by a uppercase character, or
a single underscore at file scope are not allowed. Since function
parameters are not at file scope, well, using `_this' should be
fine. Where am I going wrong?

When macros are expanded the system has not parsed the function
header. It is just so much more text to be treated according to
the macro rules.
But that's not an issue in this case, since <stdio.hcannot legally
define _this as a macro. See my other response.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #12
On Thu, 12 Jun 2008 18:02:11 -0700, Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
>Chris Thomasson wrote:
>>Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}
[...]
Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.

stdio.h cannot legally define a macro named "_this". [snip explanation]
Yes, it can: _this is reserved for use by the implementation at file
scope. This means an implementation is allowed to provide a declaration of
a function named _this in <stdio.h>. And 7.1.4 states that "Any function
declared in a header may be additionally implemented as a function-like
macro defined in the header," which does not only apply to the functions
described by the standard. Existing implementations make use of this
permission with macro definitions of _toupper and _tolower in <ctype.h>.

That said, <stdio.hcannot legally define an object-like macro named
"_this", so the code by Chris Thomasson is still perfectly fine.
Jun 27 '08 #13
Harald van Dijk <tr*****@gmail.comwrites:
On Thu, 12 Jun 2008 18:02:11 -0700, Keith Thompson wrote:
>CBFalconer <cb********@yahoo.comwrites:
>>Chris Thomasson wrote:
Something like the following is perfectly fine:

#include <stdio.h>

void foo(int _this) {
printf("%d\n", _this);
}
[...]
Not if stdio.h has (legitimately) defined a macro for _this. Using
plain this is safer, since the scope of this only extends to the
function closing '}'.

stdio.h cannot legally define a macro named "_this". [snip explanation]

Yes, it can: _this is reserved for use by the implementation at file
scope. This means an implementation is allowed to provide a declaration of
a function named _this in <stdio.h>. And 7.1.4 states that "Any function
declared in a header may be additionally implemented as a function-like
macro defined in the header," which does not only apply to the functions
described by the standard. Existing implementations make use of this
permission with macro definitions of _toupper and _tolower in <ctype.h>.
Interesting. (I overlooked function-like macros.) I think you're
right, but I wonder if that was the intent. Perhaps the committee
just didn't think about macros for non-standard functions in standard
headers.

It would have been just as easy for implementations to use __toupper
and __tolower.
That said, <stdio.hcannot legally define an object-like macro named
"_this", so the code by Chris Thomasson is still perfectly fine.
Right.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #14
On Fri, 13 Jun 2008 09:49:28 -0700, Keith Thompson wrote:
Harald van Dijk <tr*****@gmail.comwrites:
>Existing implementations
make use of this permission with macro definitions of _toupper and
_tolower in <ctype.h>.

It would have been just as easy for implementations to use __toupper and
__tolower.
Normally, this would be true, but _toupper and _tolower predate the
original C standard by several years. According to the Single UNIX
Specification, they are derived from Issue 1 of the SVID, which is from
1985. It would have been easier for the C standard to define these
functions than for implementations to rename them.
Jun 27 '08 #15

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

Similar topics

6
by: TooN | last post by:
Hi, I'm building an application with over 10thousand database entries. I was wondering if it would be useful, regarding memory load and server performance to unset/destroy objects at the moment...
1
by: Roman S. Golubin1709176985 | last post by:
Hello everybody! I wrote an project with one class (Class) and two forms (Form1, Form2): -----------------------------------Form2AndClass1Begin---------------------- ------------------ public...
4
by: pachanga | last post by:
After you destroy a Object and its send to the garbage collections, can you retrieve the object back? Also, if you can, can you destroy an object permantly with no trace of it?
2
by: jaymtz78 | last post by:
Hi, I have a huge windows application that I'm working on and I'm completely baffled. Sometimes when I try to close the application, it won't let me! I have an Exit button in my menu bar that...
3
by: Microsoft | last post by:
I am working on a VB.NET (2003) application and I am confused about object lifetimes. I have a class of objects that are created in a manager class and added to a collection in that class. I am not...
1
by: tilbyj | last post by:
Hello, I am new to .NET, and am trying to write an application that connects to a DCOM server that we use. Wonderfully (unlike with ASP) I can now import the type library for my DCOM server, and...
4
by: Olumide | last post by:
Hello - I have two classes A and B as follows: class B{ public: ~B(){ cout << "destroying B" << endl; } }; class A{
3
by: Bartholomew Simpson | last post by:
I am writing some C++ wrappers around some legacy C ones - more specifically, I am providing ctors, dtors and assignment operators for the C structs. I have a ton of existing C code that uses...
7
by: Markus Pitha | last post by:
Hello, I have a class Adjazenzmatrix with the following method and destructor: private: Adjazenzmatrix *wegmatrix; Adjazenzmatrix *distanzmatrix; ..
41
by: =?Utf-8?B?VGltIE1hcnNkZW4=?= | last post by:
Hi, I am after suggestions on the best practice declaring and destroying objects. some example code: Private Sub MySub Dim frmMyForm As MyForm Try
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
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...

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.