By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,469 Members | 1,037 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,469 IT Pros & Developers. It's quick & easy.

A NULL pointer changed after returned?

P: n/a
fix
Hi all,
I am new to C and I just started to program for a homework.
I included my code down there.
It is a fraction "class". I declared the Fraction struct, tried to
create some invalid fraction, with denominator zero.
A Fraction is created by the newFraction() function, and which in turns
call normalize() function to simplify it, but before, the normalize()
function will do a check, if the denominator is zero, it will give a
error by returning a NULL.
Everything works fine for a normal fraction, e.g. 3/4, 5/4, but if I
give a "4/0" to the function, it is frustrating.
In the normalize function, I am sure it is set to NULL, but back to
newFraction, it changed back to 4/0. But if I give a fraction that could
be simplified, such as 6/8, it is simpified and returned as 3/4 with
no problem.
Please help!
fix.

Fraction.c:
#include "Fraction.h"
void Case1c()
{
printFraction(newFraction(0,4));printf("\n");
printFraction(newFraction(4,0));printf("\n");
printFraction(newFraction(0,0));printf("\n");
}

int main(void)
{
printf("Case 1c:\n");Case1c();
return 0;
}

Fraction.h:
#include <stdio.h>

typedef struct {
int sign;
int numerator;
int denominator;
} Fraction;

int signOf(int number){
if (number < 0)
return -1;
else
return 1;
}

int gcd(int num1, int num2){
if (num1 < num2)
return gcd(num2, num1);
else
if ((num1 % num2) == 0)
return num2;
else
return gcd(num2, num1 % num2);
}

void normalize(Fraction *fr){
int factor;
if (fr->denominator == 0) // Invalid function
{
fr = NULL; // set it to NULL and return

printf("Set fr = NULL\n");
if (fr!=NULL)
printf("Not null");
else
printf("null");
return;
}
// Take the signs form the numerator and denominator to the sign variable
fr->sign *= signOf(fr->numerator);
fr->sign *= signOf(fr->denominator);

// Absolute the numerator and denominator
fr->numerator *= signOf(fr->numerator);
fr->denominator *= signOf(fr->denominator);

if (fr->numerator == 0)
{ // If the numerator is 0, simplify it to 0/1
fr->denominator = 1;
fr->sign = 1;
}
else
{ // Find the gcd of the numerator and denominator, divide them by the gcd
factor = gcd(fr->numerator, fr->denominator);
fr->numerator /= factor;
fr->denominator /= factor;
}
}
Fraction newFraction(int num, int den)
{
Fraction fr;
Fraction *frp;

fr.numerator = num;
fr.denominator = den;
fr.sign = 1;
frp = &fr;
normalize(frp);
if (frp!=NULL)
printf("Not null");
else
printf("null");

return fr;
}
void printFraction(Fraction fr)
{
if (&fr == NULL)
printf("Invalid fraction");

if (fr.sign == -1)
printf("-");
printf("%i/%i", fr.numerator, fr.denominator);
}

Nov 14 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a
fix <fi*@here.com> writes:
void normalize(Fraction *fr){
int factor;
if (fr->denominator == 0) // Invalid function
{
fr = NULL; // set it to NULL and return

printf("Set fr = NULL\n");
if (fr!=NULL)
printf("Not null");
else
printf("null");
return;


This is in the FAQ.

4.8: I have a function which accepts, and is supposed to initialize,
a pointer:

void f(int *ip)
{
static int dummy = 5;
ip = &dummy;
}

But when I call it like this:

int *ip;
f(ip);

the pointer in the caller remains unchanged.

A: Are you sure the function initialized what you thought it did?
Remember that arguments in C are passed by value. The called
function altered only the passed copy of the pointer. You'll
either want to pass the address of the pointer (the function
will end up accepting a pointer-to-a-pointer), or have the
function return the pointer.

See also questions 4.9 and 4.11.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x1f6},*p=
b,x,i=24;for(;p+=!*p;*p/=4)switch(x=*p&3)case 0:{return 0;for(p--;i--;i--)case
2:{i++;if(1)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
Nov 14 '05 #2

P: n/a

# void normalize(Fraction *fr){

This copies the Fraction* parameter value into a local variable fr.
All changes to fr itself are to this local variable and not propagated
back to the caller. It's changes to *fr (or fr->...) that are visible
to the caller.

You can instead do something like
Fraction *normalize(Fraction *fr) {
...
return fr;
}
which propagates changes back to the caller as the function yield.
You can then call
frp = normalize(frp);
if (frp!=NULL)
printf("Not null");
else
printf("null");

# frp = &fr;
# normalize(frp);

This passes the address of the structure, not the address of pointer
variable to the structure.

--
Derk Gwen http://derkgwen.250free.com/html/index.html
I hope it feels so good to be right. There's nothing more
exhilirating pointing out the shortcomings of others, is there?
Nov 14 '05 #3

P: n/a
In 'comp.lang.c', fix <fi*@here.com> wrote:
Fraction.c:
#include "Fraction.h"

<snipped>

First of all, I highly recommend that you change your code organization. It's
a very bad idea to have code included in a .h. I suggest a very common
approach as follow:

/* main.c */
#include "Fraction.h"
#include <stdio.h>

/* macros ================================================== ============ */
/* constants ================================================== ========= */
/* types ================================================== ============= */
/* structures ================================================== ======== */
/* private variables ================================================== = */
/* private functions ================================================== = */

static void Case1c (void)
{
printFraction (newFraction (0, 4));
printf ("\n");
printFraction (newFraction (4, 0));
printf ("\n");
printFraction (newFraction (0, 0));
printf ("\n");
}

/* entry point ================================================== ======= */

int main (void)
{
printf ("Case 1c:\n");
Case1c ();
return 0;
}

/* public variables ================================================== == */

/* fraction.h */
#ifndef H_FRACTION
#define H_FRACTION
/* macros ================================================== ============ */
/* constants ================================================== ========= */
/* types ================================================== ============= */
/* structures ================================================== ======== */

typedef struct
{
int sign;
int numerator;
int denominator;
}
Fraction;

/* internal public functions =========================================== */
/* entry points ================================================== ====== */

Fraction newFraction (int num, int den);
void printFraction (Fraction fr);

/* public variables ================================================== == */

#endif /* guard */

/* fraction.c */
#include <stdio.h>
#include "fraction.h"

/* macros ================================================== ============ */
/* constants ================================================== ========= */
/* types ================================================== ============= */
/* structures ================================================== ======== */
/* private variables ================================================== = */
/* private functions ================================================== = */

static int signOf (int number)
{
if (number < 0)
return -1;
else
return 1;
}

static int gcd (int num1, int num2)
{
if (num1 < num2)
return gcd (num2, num1);
else if ((num1 % num2) == 0)
return num2;
else
return gcd (num2, num1 % num2);
}

static void normalize (Fraction * fr)
{
int factor;
if (fr->denominator == 0) /* Invalid function */
{
fr = NULL; /* set it to NULL and return */

printf ("Set fr = NULL\n");
if (fr != NULL)
printf ("Not null");
else
printf ("null");
return;
}
/* Take the signs form the numerator and denominator to the sign variable
*/
fr->sign *= signOf (fr->numerator);
fr->sign *= signOf (fr->denominator);

/* Absolute the numerator and denominator */
fr->numerator *= signOf (fr->numerator);
fr->denominator *= signOf (fr->denominator);

if (fr->numerator == 0)
{ /* If the numerator is 0, simplify it to 0/1
*/
fr->denominator = 1;
fr->sign = 1;
}
else
{ /* Find the gcd of the numerator and
denominator, divide them by the gcd */
factor = gcd (fr->numerator, fr->denominator);
fr->numerator /= factor;
fr->denominator /= factor;
}
}

/* internal public functions =========================================== */
/* entry points ================================================== ====== */

Fraction newFraction (int num, int den)
{
Fraction fr;
Fraction *frp;

fr.numerator = num;
fr.denominator = den;
fr.sign = 1;
frp = &fr;
normalize (frp);
if (frp != NULL)
printf ("Not null");
else
printf ("null");

return fr;
}

void printFraction (Fraction fr)
{
if (&fr == NULL)
printf ("Invalid fraction");

if (fr.sign == -1)
printf ("-");
printf ("%i/%i", fr.numerator, fr.denominator);
}

/* public variables ================================================== == */

Note that I have no changed your code.

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #4

P: n/a
fix


Derk Gwen wrote:
# void normalize(Fraction *fr){

This copies the Fraction* parameter value into a local variable fr.
All changes to fr itself are to this local variable and not propagated
back to the caller. It's changes to *fr (or fr->...) that are visible
to the caller.

You can instead do something like
Fraction *normalize(Fraction *fr) {
...
return fr;
}
which propagates changes back to the caller as the function yield.
You can then call
frp = normalize(frp);
if (frp!=NULL)
printf("Not null");
else
printf("null");

# frp = &fr;
# normalize(frp);

This passes the address of the structure, not the address of pointer
variable to the structure.

--
Derk Gwen http://derkgwen.250free.com/html/index.html
I hope it feels so good to be right. There's nothing more
exhilirating pointing out the shortcomings of others, is there?

Yup thanks!

Nov 14 '05 #5

P: n/a
fix


Ben Pfaff wrote:
fix <fi*@here.com> writes:

void normalize(Fraction *fr){
int factor;
if (fr->denominator == 0) // Invalid function
{
fr = NULL; // set it to NULL and return

printf("Set fr = NULL\n");
if (fr!=NULL)
printf("Not null");
else
printf("null");
return;

This is in the FAQ.

4.8: I have a function which accepts, and is supposed to initialize,
a pointer:

void f(int *ip)
{
static int dummy = 5;
ip = &dummy;
}

But when I call it like this:

int *ip;
f(ip);

the pointer in the caller remains unchanged.

A: Are you sure the function initialized what you thought it did?
Remember that arguments in C are passed by value. The called
function altered only the passed copy of the pointer. You'll
either want to pass the address of the pointer (the function
will end up accepting a pointer-to-a-pointer), or have the
function return the pointer.

See also questions 4.9 and 4.11.


Ah...... I got you, so that means if I change the content in the struct,
i.e. changing the signs, denom and numerators, the pointer hasn't
changed, but if I point it to NULL, I am actually changing the pointer
so it reverts to the original value outside the function body.
If I am to return a pointer, I am curious that if I return a pointer to
a variable created inside the function, will the variable be garbage
collected but the pointer still pointing to that? I was learning Java
last semester and I have no trouble with pointers.......

Nov 14 '05 #6

P: n/a
fix
Is this the order? Does C have any privacy (private
functions/variables)? And what is entry point?
Thanks.
/* macros ================================================== ============ */
/* constants ================================================== ========= */
/* types ================================================== ============= */
/* structures ================================================== ======== */
/* private variables ================================================== = */
/* private functions ================================================== = */
/* entry point ================================================== ======= */
/* public variables ================================================== == */

Nov 14 '05 #7

P: n/a
In 'comp.lang.c', fix <fi*@here.com> wrote:
Is this the order?
It's not /the/ order, it's mine, but actually, my experience has shown to me
that's it's hard to have another one!
Does C have any privacy (private
functions/variables)?
sure, by the use of the 'static' word.
/* macros ================================================== ============ */
/* constants ================================================== ========= */
/* types ================================================== ============= */
/* structures ================================================== ======== */
/* private variables ================================================== = */
/* private functions ================================================== = */
/* entry point ================================================== ======= */
/* public variables ================================================== == */ And what is entry point?


This list was retrieved from a 'main.c' which is the source file that holds
the main() function. This function being by-definition the top-level function
of the application, it is also the unique entry point (the first entry) of
the module.

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #8

P: n/a
fix <fi*@here.com> writes:
Ah...... I got you, so that means if I change the content in the
struct, i.e. changing the signs, denom and numerators, the pointer
hasn't changed, but if I point it to NULL, I am actually changing the
pointer so it reverts to the original value outside the function body.
If I am to return a pointer, I am curious that if I return a pointer
to a variable created inside the function, will the variable be
garbage collected but the pointer still pointing to that? I was
learning Java last semester and I have no trouble with pointers.......


C doesn't have garbage collection.

You really need to read the FAQ. This is also a FAQ.

7.5a: I have a function that is supposed to return a string, but when
it returns to its caller, the returned string is garbage.

A: Make sure that the pointed-to memory is properly allocated.
For example, make sure you have *not* done something like

char *itoa(int n)
{
char retbuf[20]; /* WRONG */
sprintf(retbuf, "%d", n);
return retbuf; /* WRONG */
}

One fix (which is imperfect, especially if the function in
question is called recursively, or if several of its return
values are needed simultaneously) would be to declare the return
buffer as

static char retbuf[20];

See also questions 7.5b, 12.21, and 20.1.

References: ISO Sec. 6.1.2.4.
--
"Given that computing power increases exponentially with time,
algorithms with exponential or better O-notations
are actually linear with a large constant."
--Mike Lee
Nov 14 '05 #9

P: n/a

"fix" <fi*@here.com> wrote in message news:
Is this the order? Does C have any privacy (private
functions/variables)? And what is entry point?
Thanks.

The main unit of organisation for C is the file.
Typically a file will contain either one complex function, or a list of
related functions.
For example, my BASIC interpreter has a single, very complex function,
basic(const char *script), which allows a BASIC script to be run.
Needless to say there are many sub-functions which that function calls, for
instance there is a function to calculate the value of an algebraic
expression, a function to print output, a function to execute a conditional
jump. However I don't want the user to call any of these functions directly,
so they are private to that file, or static. There is only one entry point,
the basic() function itself.
There are also private variables. For instnace the first thing I do is read
all the line numbers and store them in a global array for fast access.
Obviously I don't want anyone messing with that array either, so these
variables are also declared static, or local to that file.
Nov 14 '05 #10

P: n/a
fix


Ben Pfaff wrote:
fix <fi*@here.com> writes:

Ah...... I got you, so that means if I change the content in the
struct, i.e. changing the signs, denom and numerators, the pointer
hasn't changed, but if I point it to NULL, I am actually changing the
pointer so it reverts to the original value outside the function body.
If I am to return a pointer, I am curious that if I return a pointer
to a variable created inside the function, will the variable be
garbage collected but the pointer still pointing to that? I was
learning Java last semester and I have no trouble with pointers.......

C doesn't have garbage collection.

You really need to read the FAQ. This is also a FAQ.

7.5a: I have a function that is supposed to return a string, but when
it returns to its caller, the returned string is garbage.

A: Make sure that the pointed-to memory is properly allocated.
For example, make sure you have *not* done something like

char *itoa(int n)
{
char retbuf[20]; /* WRONG */
sprintf(retbuf, "%d", n);
return retbuf; /* WRONG */
}

One fix (which is imperfect, especially if the function in
question is called recursively, or if several of its return
values are needed simultaneously) would be to declare the return
buffer as

static char retbuf[20];

See also questions 7.5b, 12.21, and 20.1.

References: ISO Sec. 6.1.2.4.


Thanks, where can I get the FAQ?

Nov 14 '05 #11

P: n/a
fix


Emmanuel Delahaye wrote:
In 'comp.lang.c', fix <fi*@here.com> wrote:

Is this the order?

It's not /the/ order, it's mine, but actually, my experience has shown to me
that's it's hard to have another one!

Does C have any privacy (private
functions/variables)?

sure, by the use of the 'static' word.

/* macros ================================================== ============ */
/* constants ================================================== ========= */
/* types ================================================== ============= */
/* structures ================================================== ======== */
/* private variables ================================================== = */
/* private functions ================================================== = */
/* entry point ================================================== ======= */
/* public variables ================================================== == */


And what is entry point?

This list was retrieved from a 'main.c' which is the source file that holds
the main() function. This function being by-definition the top-level function
of the application, it is also the unique entry point (the first entry) of
the module.


Aha..... thanks!

Nov 14 '05 #12

P: n/a
fix


Malcolm wrote:
"fix" <fi*@here.com> wrote in message news:
Is this the order? Does C have any privacy (private
functions/variables)? And what is entry point?
Thanks.


The main unit of organisation for C is the file.
Typically a file will contain either one complex function, or a list of
related functions.
For example, my BASIC interpreter has a single, very complex function,
basic(const char *script), which allows a BASIC script to be run.
Needless to say there are many sub-functions which that function calls, for
instance there is a function to calculate the value of an algebraic
expression, a function to print output, a function to execute a conditional
jump. However I don't want the user to call any of these functions directly,
so they are private to that file, or static. There is only one entry point,
the basic() function itself.
There are also private variables. For instnace the first thing I do is read
all the line numbers and store them in a global array for fast access.
Obviously I don't want anyone messing with that array either, so these
variables are also declared static, or local to that file.


Got it! thanks.

Nov 14 '05 #13

P: n/a
fix <fi*@here.com> writes:
Thanks, where can I get the FAQ?


1. Don't quote 45 lines to add 1 line.
2. Learn to use search engines.
--
"It would be a much better example of undefined behavior
if the behavior were undefined."
--Michael Rubenstein
Nov 14 '05 #14

P: n/a
fix wrote:
.... snip ...
Thanks, where can I get the FAQ?


Just scan the sig lines of various contributors to this newsgroup.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #15

P: n/a
On Sun, 29 Feb 2004 11:13:24 -0600, fix <fi*@here.com> wrote:


Ben Pfaff wrote:
fix <fi*@here.com> writes:

void normalize(Fraction *fr){
int factor;
if (fr->denominator == 0) // Invalid function
{
fr = NULL; // set it to NULL and return

printf("Set fr = NULL\n");
if (fr!=NULL)
printf("Not null");
else
printf("null");
return;

This is in the FAQ.

4.8: I have a function which accepts, and is supposed to initialize,
a pointer:

void f(int *ip)
{
static int dummy = 5;
ip = &dummy;
}

But when I call it like this:

int *ip;
f(ip);

the pointer in the caller remains unchanged.

A: Are you sure the function initialized what you thought it did?
Remember that arguments in C are passed by value. The called
function altered only the passed copy of the pointer. You'll
either want to pass the address of the pointer (the function
will end up accepting a pointer-to-a-pointer), or have the
function return the pointer.

See also questions 4.9 and 4.11.


Ah...... I got you, so that means if I change the content in the struct,
i.e. changing the signs, denom and numerators, the pointer hasn't
changed, but if I point it to NULL, I am actually changing the pointer
so it reverts to the original value outside the function body.
If I am to return a pointer, I am curious that if I return a pointer to
a variable created inside the function, will the variable be garbage
collected but the pointer still pointing to that? I was learning Java
last semester and I have no trouble with pointers.......


Almost.

C passes arguments to functions by value. This means the function
receives a private copy of the argument. This private copy ceases to
exist when the function returns to its caller. Any change to the
argument made by the function is lost when the function returns
because the change was made only to the private copy which no longer
exists. The original variable in the calling function was never
changed and therefore never reverts.

If the argument is a pointer, then the function can dereference the
pointer and make "permanent" changes to the object pointed to that
will persist after the function returns.

There is no garbage collector in C. If you allocate memory in a
function, that memory remains allocated until explicitly freed. This
allocation is completely independent of function boundaries. (One
frequent problem encountered is not returning the pointer to such
memory which immediately creates a memory leak.)
<<Remove the del for email>>
Nov 14 '05 #16

P: n/a
On Sun, 29 Feb 2004 11:18:25 -0600, fix <fi*@here.com> wrote:
Is this the order? Does C have any privacy (private
functions/variables)? And what is entry point?
Thanks.
/* macros ================================================== ============ */
/* constants ================================================== ========= */
/* types ================================================== ============= */
/* structures ================================================== ======== */
/* private variables ================================================== = */
/* private functions ================================================== = */
/* entry point ================================================== ======= */
/* public variables ================================================== == */


Functions declared static are visible only within the translation unit
in which they appear.

Static variables declared at file scope are visible to all functions
but again only those within the same translation unit. (Static has a
different meaning for variables declared inside a function.)

Entry point has multiple meanings.

In general, it means the definition of block of code which be the
target of a reference from a different translation unit. It is how
the linker resolves references to external functions. In C source
code, it is a function with the external attribute (the default if
static is not specified).

In the context of the post you were replying to, I think the
author intended something more specific and will let him comment.

The important point in that message which you seem to have glossed
over is that header files should not contain code or object
definitions. Header files should be restricted to typedef's,
prototypes, macros, and object/variable declarations. That is, they
should provide descriptions but not actually generate anything.
<<Remove the del for email>>
Nov 14 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.