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?

11
  • 1
    Do reversed steps of the allocation or just exit your program and have the OS free the memory. Commented Aug 4, 2021 at 11:35
  • 1
    did you try free(bglobal.arr)? Commented Aug 4, 2021 at 11:36
  • 1
    Register an exit handler in init() that frees the allocated memory when the program exits. Or provide an uninit() function that the client code can call themselves to free the resources. Commented Aug 4, 2021 at 11:49
  • 1
    You can call atexit from your init function. Commented Aug 4, 2021 at 12:11
  • 1
    Although it is cleaner to free everything that was allocated, it is usually only the chronic memory leaks that cause problems. Commented Aug 4, 2021 at 12:16

2 Answers 2

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);
Sign up to request clarification or add additional context in comments.

4 Comments

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 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
This is annoying but this is assignment.
@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.
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);
}

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.