the object's data. So, in other words when we return from f(), we should be
example lets call the latter function fx(). In fx() function the object's
modified or used as needed.
Hello,
This post is in reference to my last post called "static array question" and
therefore may be considered as a sequel to previous discussions between I and
the posters of that post.
And, furthermore, the allocation you made inside f() is leaked, since
you don't have any pointer to it in the caller, and thus can't possibly
free it.
So, resuming from option#2 to correct this,
=======================
typedef struct passCode {
int TOUCHES;
} PASSCODE;
// NOTES
////////////
// a) A struct of type passCode has been typedefed as PASSCODE
// b) Also a pointer of type PASSCODE called "y" has been created in the
function
// c) The "y" pointer is assigned an address pointing to memory allocated on
the
// heap which contains the PASSCODE object
// d) r and TOUCHES never used in the function!
// e) PASSCODE object is freed in the function.
// f) Data assigned to the PASSCODE object in f1() will never be visible in
main.
void f( int r, int TOUCHES)
{
PASSCODE *y;
y = malloc(sizeof(struct passCode));
y->TOUCHES = TOUCHES;
free(y);
y = NULL;
}
int main()
{
f(1, 47);
return 0;
}
======================
(I choose to overlook the minor point of a missing closing parenthesis).
Ooopps, My mistake!
Option#3
======================
While valid code, it's not clear why f() takes PASSCODE* as a parameter,
considering that it never uses it. Why not
PASSCODE *f(int u)
{
PASSCODE *r = malloc (sizeof (PASSCODE));
r->TOUCHES = u
return r;
}
Through out my posts this has been an ongoing issue which I chose to
temporarilly disregard due to the fact that I had much more serious issues
with structures passing by value and passing by reference. Via the
communities, I have finally learned the differences which I am very greatfull
of. However, the issue of why f() takes PASSCODE* as a parameter and
considering that it is never used will be now further discussed at the end of
this post once and for all! :)
Ok, just as long as you realize that a) variable e is never used, and b)
assignment y = &e is pointless since b.1) the function never uses its
parameter, and b.2) y gets reassigned immediately afterwards. Make it
Understood!
Option #4
====================
While valid code, it's not clear why f() uses two mechanisms to report
the same value: a return value, and a by-reference parameter. You can
eliminate this redundancy in two ways: either drop the parameter as I've
shown above under Option #3, or drop the return value:
oooopppss, that return statement wasn't supposed to be there, sorry, my typo!
OK, modulo the same observation that e is never used.
This now very well understood!
It's also passed by reference.
Okay! thankyou!
Now, I have to tell you that, even though I got pointers to pointers to work
in VC++, double indirection is not supported by my MCU compiler, and I did
report this to them and they have confirmed to me that there is an issue and
will be corrected in their next versions to come. Therefore, in the mean time
I opt for option #3 where the famous issue comes once more and pointed out by:
You still don't use the initial value of the parameter. I still don't
understand why you insist on having this parameter at all.
So here it is:
============================================
Okay, This was hard for me to explain in previous posts because I was very
confused, but lets get some ground rules that I have to go by.
--- Rule #1 ----
I need a function (in this case f();) that contains 3 memory operations.
They are:
a) It must create an object on the heap and imediately assign data to its
elements
b) It must be able to only modify the object's elements !
c) It must be able to free the object.
--- Rule #2 ----
Once the object is created in f(), and we return from f(), we need access to
the object's data. So, in other words when we return from f(), we should be
able to pass the pointer to the object by value (I don't need it by reference
at this point since I only need the object's informations) to some other
function(s), for example lets call the latter function fx().
--- Rule #3 ----
When I come out of fx() function, I should be able to call the f() function
to free the object.
--- Rule #4 ----
We never, ever, ever execute, Rule #1 clause -b- without having executed
Rule #1 clause -a- before. Meaning that before we modify an object, it must
have been created.... This is very obvious and therefore no big deal. Rule #
1 clause -b- is just there if we ever might want to modify the data's object
after its been created and innitialized by Rule #1 clause -a-.
So given the above constraints, what is wrong if I do this:
(THIS BELOW CODE COMPILES WITHOUT ERROS AND WORKS APPROPRIATELY)
=======================
#include <stdio.h>
#include <stdlib.h>
typedef struct passCode {
int TOUCHES;
} PASSCODE;
// NOTES
////////////
// a) A struct of type passCode has been typedefed as PASSCODE
// b) A "y" pointer of type PASSCODE is created and assigned NULL in main.
// c) Although, set to NULL, the pointer to PASSCODE is passed into f() by
value
// and returned to main and pointing to an object with pertinant
informations.
// d) The pointer to PASSCODE is passed to other functions so the object's
data
// can be used.
// e) Data assigned to the PASSCODE object in f() will be visible in main
and in
// other functions.
// f) PASSCODE object is finally freed in f().
PASSCODE *f(PASSCODE *r, int CMD, int TOUCHES)
{
switch(CMD)
{
case 1: // CREATE
r = malloc(sizeof(PASSCODE));
if(r == NULL)
{// warn that memory not available!
}
case 2: // ASSIGN DATA
r->TOUCHES = TOUCHES;
break;
case 3: // FREE IT
free(r);
r = NULL;
}
return r; // RETURN THE POINTER REGARDLESS IF NULL OR NOT!
}
void fx(PASSCODE *q)
{
int a;
a = q->TOUCHES;
}
int main()
{
PASSCODE *y = NULL;
y = f(y, 1, 7); // Create the object!
fx(y); // Use the object's information in some other function(s)!
f(y, 2, 8); // ONly modify the object's data!
fx(y); // Use the object's modified information in some other
function(s)!
y = f(y, 3, 7); // Finally, free that object!
return 0;
}
=============================
For one, since it was suggested to not pass the PASSCODE parameter in f()
function, then how would the above scenario work.... I can't really do this
because what would happen when I come back into f() function to free the
original pointer's object ?????? So I can't do this!
=====================================
PASSCODE *f(int CMD, int TOUCHES)
{
PASSCODE *r;
switch(CMD)
{
case 1: // CREATE
r = malloc(sizeof(PASSCODE));
if(r == NULL)
{// warn that memory not available!
}
...
======================================
And furthermore I can't declare the pointer's object in the switch code
like this:
=====================================
PASSCODE *f(int CMD, int TOUCHES)
{
switch(CMD)
{
case 1: // CREATE
PASSCODE *r = malloc(sizeof(PASSCODE));
if(r == NULL)
{// warn that memory not available!
}
...
======================================
cause it gives the following error!
c:\_DTS_PROGRAMMING\C_PROGRAMMING\c\PassingStructures_PersonalExamples\PASSING_STRUCTURES\Can_Delete.c(23):
error C2275: 'PASSCODE' : illegal use of this type as an expression
Look, I might be very wrong about how I am going about all this, but I am no
expert in C and so again all feedback is appreciated.
--
Best regards
Roberto