1

I am trying to create a simple ADT using a structure that takes 2 dates. Then returns an age. It must use a Header file, a source file for the Header file, and a main file.

This is what I have it runs and nothing happens. Can someone tell me what i am doing wrong?

age.h

#ifndef AGE_H_

#define AGE_H_

typedef struct getage * Age;

#define MAX  5

Age get_Age(int birthYear, int yearNow);

void age_Destroy(Age a);


#endif

age.c

#include <stdio.h>

#include "age.h"


struct getage {

       int birthYear;

       int yearNow;

};

Age a[1];

Age get_Age(int birthYear, int yearNow){

             int giveAge = 0;

             giveAge = a[0]->yearNow - a[0]->birthYear;

             printf("%d",giveAge);

             return 0;

            }

void age_Destroy(Age a){

                     free(a);

     }

main.c

#include <windows.h>

#include <stdio.h>

#include "age.h"


void age_print(Age a);

void age_print(Age a){

        printf("%d\n", &a);

}



int main() {

    Age a;

    get_Age(1986, 2020);
    
    age_print(a);

    printf("%d\n", &a);

    system("pause");

    //age_Destroy(a);
    
    
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
Syntax2k6
  • 13
  • 2
  • 1
    One of your wrong points is `printf("%d\n", &a);`. This is passing `Age*` to `%d`, which requires `int`, and invoking *undefined behavior*. – MikeCAT Jul 17 '20 at 23:22
  • See [Is it a good idea to typedef pointers?](https://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers) — TL;DR usually not, but function pointers might be an exception. – Jonathan Leffler Jul 17 '20 at 23:25
  • 1
    Your code never assigns any values to an instance of your struct. You define get_Age to return a pointer to your struct but you return an int. You never allocate an instance to the variable a. It is simply a pointer to a struct, not an instance of a struct. – Jim Rogers Jul 17 '20 at 23:26
  • @JimRogers — it returns a null pointer, not an `int`. `0` is a legitimate representation for a null pointer. – Jonathan Leffler Jul 17 '20 at 23:26
  • @JimRogers Actually there are no instance of the struct allocated. Values are read from `NULL` in the function `get_Age`. – MikeCAT Jul 17 '20 at 23:34
  • What should the function `age_print` do? Note that the function cannot access the members of the structure because the declaration of structure is not provided for `main.c` (inside the header). – MikeCAT Jul 17 '20 at 23:42

1 Answers1

1

What are wrong:

  • In the function get_Age:
    • Instead of allocating structures, a[0] (global variable, initialized to NULL) is dereferenced.
    • 0 (converted to NULL) is returned instead of returning an age.
  • In the function age_Destroy:
    • free() is used without declaration nor including proper header.
  • In the function age_print:
    • Data having wrong type is passed to printf(): %d requests int but Age* is passed.
  • In the function main:
    • The return value of get_Age is dropped.
    • Data having wrong type is passed to printf(): %d requests int but Age* is passed.

Fixed code that won't cause Segmentation Fault nor undefined behavior:

age.h (not changed)

#ifndef AGE_H_

#define AGE_H_

typedef struct getage * Age;

#define MAX  5

Age get_Age(int birthYear, int yearNow);

void age_Destroy(Age a);

#endif

age.c

#include <stdio.h>

#include <stdlib.h> // for malloc() and free()

#include "age.h"


struct getage {

       int birthYear;

       int yearNow;

};

Age get_Age(int birthYear, int yearNow){

        Age a = malloc(sizeof(*a)); // allocate a structure

        if (a == NULL) { perror("malloc"); exit(1); }

        a->yearNow = yearNow; // assign data

        a->birthYear = birthYear;

        int giveAge = 0;

        giveAge = a->yearNow - a->birthYear;

        printf("%d",giveAge);

        return a; // return pointer to the allocated structure

}

void age_Destroy(Age a){

        free(a);

}

main.c

#include <stdlib.h> // more portable header for system()

#include <stdio.h>

#include "age.h"


void age_print(Age a);

void age_print(Age a){

        printf("%p\n", (void*)a); // use valid combination of format and data

}



int main() {

    Age a;

    a = get_Age(1986, 2020); // assign the return value
    
    age_print(a);

    printf("%p\n", (void*)a); // use valid combination of format and data

    system("pause");

    age_Destroy(a); // enable freeing
    
    
}

(Some behavior may look weird, but I believe this is valid because not desired behavior is described.)

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • Thank you so much. Got exactly want i wanted after a few tweaks of the solution you gave. Thanks again. – Syntax2k6 Jul 20 '20 at 15:06