问题描述:

I'm writing a socket listener in C. Whenever it accepts, it creates a new thread (detached) recv the data and process.

But everytime, I need to manually call close(socket_descriptor). Had it been C++, I could have in someway choose to close it inside a destructor.

I was trying to find out something that provides me same behaviour.

Basically, I want to create something like shared_ptr in C.

Is there anyway in C where one can get a signal or a notification when an object is going out of scope?

网友答案:

No, that's not an inherent feature of C ... to enable something like what you're asking for you would have to create some sort of call-back mechanism that would use a look-up table to match an object to its "destrutor", and call that general call-back function at the end of every function you write, or more likely, at the end of every scope where an object was declared. I'd consider that very messy and complicated, and in the end, that's probably much more hassle than it's worth, i.e., you could simply use a goto and write all your clean-up code at the end of the function (I know in-general using goto's is considered very bad style, but for jumping to clean-up code at the end of a function, they can actually make the code much cleaner than the alternative which is to keep repeating the same clean-up code every time there's an error).

For example, suppose you had a function that allocated some memory and opened a file descriptor at some early point in the function, but then if there were some errors, could not continue ... you can't simply return an error code, you have to-do some clean-up, but it would be a pain to repeat the clean-up code over and over again right in the middle of the code:

int my_function()
{
    int* array_on_heap = malloc(ARRAYSIZE * sizeof(int));
    int file_descriptor;

    //...some code

    if (some_ptr == NULL)
        goto error_cleanup;

    //...some more code

    if (some_other_pointer != some_ptr)
        goto error_cleanup;

    //...even more code

    //normal return with no error
    return 0;

    error_cleanup:
        //clean-up code in case there was an error
        free(array_on_heap);
        close(fd);
        return -1;
}

This deliberate and judicious use of the goto here creates a very concise area of the function where destruction and clean-up can take place, and you don't have to worry about possibly missing clean-up functionality had you decided to sprinkle clean-up code in the actual "mechanics" of the function itself.

网友答案:

There is no such thing as an automatic destructor in plain old C. Have you considered doing that through a garbage collector?

For example, you could use the Boehm-Demers-Weiser conservative garbage collector to allocate your objects and then call GC_REGISTER_FINALIZER to close the socket descriptor whenever the object becomes inaccessible.

Another solution could be to wrap the client's callback function into another function which simply calls the callback and then closes the socket. This way you wouldn't have to close it explicitly in every callback function.

网友答案:

There is only one way you do it in "raw" C:

void abc_init (parameters);

void abc_cleanup (parameters);

where all abc functions belong to the module abc, which consists of abc.h and abc.c. Allocation of objects can then either be handled by the caller to the abc module, or by the module itself:

// alternative 1, leave allocation to the caller

#include "abc.h"

int main()
{
  Abc_t x;

  abc_init(&x);

  ...

  abc_cleanup(&x);
}


// alternative 2, the module handles allocation

// abc.c

static Abc_t* x;

void abc_init (parameters)
{
  x = some_sort_of_allocation();
  set x based on parameters
}


...

void abc_cleanup (parameters)
{
  cleanup x
}
相关阅读:
Top