How can I make sure the caller passes the malloc'd pointer?

I have a function that redirects the pointer specified as an argument to the new size. Now the problem is that - according to the man page - realloc requires a pointer that was returned by malloc or calloc before.

How can I make sure the caller passes a pointer that meets these requirements? It seems that there are no built-in C-mechanics (such as type classifiers or anything else).

Now, before I restructure my API (since I believe that the function, since it is not reliable enough now), can you confirm that I did not miss anything?

Thanks in advance.

Edit: One solution would obviously be malloc in the function. The problem is that the caller does not "see" the distribution. That way, I will need to explicitly say in the docs that it should free the pointer. This is even worse than expecting them to provide a malloc'd pointer (which would mean that the caller must free it).

What I really want is what blocks abuse during compilation. This is a pony .; -)

+6
c realloc
source share
11 answers

How can I make sure the caller passes a pointer that meets these requirements?

Documentation.

Define an API.

If the person recording the caller refuses to follow the API, everything happens with an error. They refused to play by your rules, and everything crashed. What did they expect?

+10
source share

At the end of the day, pointers to C are nothing more than a machine word that may or may not indicate managed data within the process memory that may or may not be assigned to malloc. There is no such information attached to any index.

Just add a big, bold API warning. If the documentation clearly states: β€œnever skip this function pointer that was not malloc'd,” and someone does this nonetheless and gets errors / failures, this is not your fault - here you cannot program the defense here.

+4
source share

You cannot determine if a region was indicated by the pointer [m|c]alloc(); 'd. You can only define your API and hope that its API users will follow it.

Is allocating memory itself (called) prohibitive? You can still make the initial distribution using realloc(NULL, size); if you are connected by this.

Additional information about your problem will be pleasant.

+2
source share

One possible way. Annotation.

 foo.c #include "foo.h" struct foo{ ... } ; foo *newFoo(...) void resize(foo *f) foo.h struct foo; typedef struct foo; caller.c foo *myfoo; myfoo = newFoo(..) resize(myfoo); 
+2
source share

How should a user get this malloc'ed pointer in the first place? Is it not possible that it is received by another function in your API? Otherwise, it sounds like boilerplate code for me, I need to allocate a piece of memory using malloc before calling my function.

In your situation, I would try this. When the caller receives a valid pointer through a function, I provide and release it through another function. Even better, wrap it all in an opaque structure.

 my_param_type my_param = init_param(....); ... my_function_that_wants_malloc(.....,my_param); ... free_param(my_param); 

Does this make sense in your API?

Having its own type, it will be clear even to the most lame user that he should receive it through the expected init_param () function.

+2
source share

You can save a static pointer inside your function and call realloc itself. Return the static pointer. Thus, the user has no problems with distribution or release. This variable will be automatically freed when the process freezes.

Keep in mind that if realloc fails, it returns a null pointer, but the original malloc'ed memory remains untouched, this is a common source of memory leaks.

0
source share

Change your implementation to not use realloc. If the buffer passed is too small, simply malloc the new larger and memcpy contents of the buffer passed to it. This will improve the usability of your API due to extreme loss of performance.

0
source share

If you have a pointer value, there is no (standard) way to determine if that pointer value was returned by malloc() . If you have a deep understanding of how dynamic memory allocation works on your platform, you can make an educated guess based on the value of the pointer, but even this is not a guarantee that you are looking at what the return value from malloc() is actually malloc() as opposed to shifting the value from this (for example, *ptr = malloc(10); foo(&ptr[5]); ).

One strategy that may or may not be worth the effort (IME, it’s not) is to hide malloc() , realloc() and free() behind some kind of memory manager that keeps track of allocated pointers and sizes. Instead of calling realloc() your code will call the resize function in the memory manager, which will return an error code if the pointer passed to it is not on the list of managed pointers.

0
source share

Create a custom data type that is a renamed void pointer.

 typedef void* myPointerType; 

Write a allocation function (which can be a simple wrapper around malloc ) that the user should use to allocate memory.

 myPointerType myAllocateFunction (size_t size) { return (myPointerType)(malloc(size)); } 

You would also like to create an appropriate β€œfree” function.

Now, your function (the one that runs realloc ) takes the myPointerType object as a parameter instead of a generic pointer. You can drop it to void* for use with realloc . To get around this, the user must manually point the non- malloc ed pointer to myPointerType , but you can indicate in your documentation that listing in and out of myPointerType not allowed (so if they do this and their applications crashes, it is because they misused API).

There are even more powerful ways you can provide this, but I'm not sure if this will be worth the trouble. You cannot completely fool the API (you would be surprised at how fools these days are capable). No matter what you ultimately implement, the best way to make sure your API is being used correctly is to provide clear and complete documentation.

You're in your own way for a pony, sorry.

0
source share

If you are looking for compile-time checking, the only thing you can really do is declare a new type that is returned by "approved" distribution calls. I would suggest something like:

  typedef struct MEM_INFO {void * ptr;  int allocsize;  struct * privateMemInfo priv;} ALLOCMEM [0];

PrivateMemInfo will be defined in your .c file, and not in the header, thereby somewhat protecting the fields from it. Note that since ALLOCMEM will be an array type, ptr and allocsize will always be available using the arrow operator, not the dot. A routine that takes ALLOCMEM as a parameter will naturally get a pointer to ALLOCMEM, allowing it to perform the "beautifully" move. Thus, for example, one could use:

  ALLOCMEM foo = {0};
   if (reallocate (foo, 12345)> = 0) / * It worked * /
0
source share

That way, I will need the documents that he needs to free the pointer. This is even worse than expecting them to provide malloc'd (which would mean that the caller must release it).

In C libraries, this is a common practice:

0
source share

All Articles