0

I have three files

struct.h  struct.c main.c

struct.h contains declaration of structs and some functions
struct.c contains global variable bglobal an instance of struct b and function implementations which use bglobal. It includes .h file
main.c call some of the functions declared in struct.h. It also includes .h file
struct.h contains two struct

struct a{
int *s
}
struct b{
struct a* arr
}
void init();
void more();

struct.c file

#include"struct.h"
struct b bglobal;
void init(){
   bglobal.arr = malloc(sizeof(struct a)*5);
}
void more(){
   *bglobal.arr[0].name = 'I';
}

main.c file

#include "main.h"
int main(){
init();
more();
}

I want that at end of program memory allocated to bglobal.arr get freed up. Using valgrind it says some bytes still reachable. How to achieve this?

2 Answers2

3

I want that at end of program memory allocated to bglobal.arr get freed up.

Add a complement function to init()

int main(){
  init();
  // do stuff
  uninit();  // this functions frees resources.
}

If struct.h does not allow improvement, make a local function in main.c.

void uninit(void) {
  extern struct b bglobal; // Take advantage that bglobal is not static
  free(bgolbal.arr);
}

bgolbal.arr = malloc(sizeof(struct b)*5); allocates to the wrong type. .arr is a struct a*. Allocate to the referenced object instead as it is easier to code right, review and maintain.

bgolbal.arr = malloc(sizeof *bgolbal.arr * 5);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • I cant add anything to str.h. So this method will not work as uninit() will be implemented in str.c but cant be referenced in main.c. – aquib nawaz Aug 04 '21 at 12:36
  • @aquib nawaz In `main.c` , `void uninit(void) { extern struct b bglobal; free(bgolbal.arr); }`. Take advantage that `bglobal` is not `static`. or better fight the questionable requirement "I can't add anything to struct.h." as `struct.c` is poorly written – chux - Reinstate Monica Aug 04 '21 at 12:53
  • This is annoying but this is assignment. – aquib nawaz Aug 04 '21 at 12:59
  • @aquib nawaz, go with `atexit()` approach then. As your coding experience grows, you will see that requirements are negotiable. Do not get stuck is a weak design. – chux - Reinstate Monica Aug 04 '21 at 13:02
2

You'll need to add a cleanup function to struct.c to free the memory. And since you can't reference that function from outside the module, you can set it up with atexit from init to be called when the program exits.

static void cleanup() {
    free(bglobal.arr);
}

void init(){
   bglobal.arr = malloc(sizeof(struct a)*5);
   atexit(cleanup);
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Given OP's limitation, this is good - aside from the side issue of the mis-type in `sizeof(struct a)`. I'd also `free(bglobal.arr);` --> `free(bglobal.arr); bglobal.arr = 0;` to cope with other potential `atexit()` using `bglobal.arr`. – chux - Reinstate Monica Aug 04 '21 at 13:05