tags:

views:

717

answers:

10
+3  A: 

You cannot check, except some implementation specific hacks.

Pointers have no information with them other than where they point. The best you can do is say "I know how this particular compiler version allocates memory, so I'll dereference memory, move the pointer back 4 bytes, check the size, makes sure it matches..." and so on. You cannot do it in a standard fashion, since memory allocation is implementation defined. Not to mention they might have not dynamically allocated it at all.

You just have to assume your client knows how to program in C. The only un-solution I can think of would be to allocate the memory yourself and return it, but that's hardly a small change. (It's a larger design change.)

GMan
A pointer could be not null but still not have buf_siz bytes allocated. I don't think there's really any way to check what the asker wants.
Ibrahim
Oops, I sped-read the question.
GMan
Ok, how about this? Since this is C, the client probably used `malloc` which does return a `NULL` pointer if it were unable to allocate memory. So ... in `malloc` we trust?
Jacob
It's up to the client to make sure malloc worked before calling the function, if that's what you're saying.
GMan
@jacob - I do know that we can check down at malloc ... but if the client forget to do malloc then it results in segmentation fault .. and i want to avoid it.
codingfreak
No, what I'm saying is if the client used `malloc` it would return NULL if it couldn't allocate memory. Of course, that doesn't stop the client from passing a pointer which wasn't even used with `malloc` ... never mind.
Jacob
Yea. The end conclusion is your function should do one thing and one thing only. Imagine the overhead if every function made sure the memory it was accessing from parameters was valid. Just have your function do what it's suppose to do.
GMan
@GMan - Yeah I do agree with you ... but I want to know whether I can do it or not ... I know that my function will be used by a good C programmer and so on ... I got this doubt on whether checking is possible or not ... It is not wrong in knowing things we dont know
codingfreak
The answer is you *could* but it wouldn't follow any standard.
GMan
+2  A: 

You can't check with anything available in standard C. Even if your specific compiler were to provide a function to do so, it would still be a bad idea. Here's an example of why:

int YourFunc(char * buf, int buf_size);

char str[COUNT];
result = YourFunc(str, COUNT);
Mark Ransom
@Mark - In the code you are assigning str as an array of size COUNT .. hence in 'YourFunc' I can still perform operations like strcpy within the size of buf_size. But if str is just a char pointer then trying to perform any strcpy operation of size buf_size will result in a 'Segmentation Fault'
codingfreak
That's VERY VERY wrong, codingfreak. The segmentation fault happens if 'str' is a char pointer pointing at memory you're not allowed to access. It doesn't happen because 'str' is a char pointer, it happens because you ask the program to do something it's not allowed to do.
gnud
A: 

No, you can't. You'll notice that no functions in the standard library or anywhere else do this. That's because there's no standard way to tell. The calling code just has to accept responsibility for correctly managing the memory.

Chuck
@Chuck if there is no standard library function to check it is there any other way out .. ?
codingfreak
+1  A: 

No, in general there is no way to do this.

Furthermore, if your interface is just "pass a pointer to a buffer where I will put stuff", then the caller may choose not to allocate memory at all, and instead use a fixed size buffer that's statically allocated or an automatic variable or something. Or perhaps it's a pointer into a portion of a larger object on the heap.

If your interface specifically says "pass a pointer to allocated memory (because I'm going to deallocate it)", then you should expect that the caller will do so. Failure to do so isn't something you can reliably detect.

Greg Hewgill
+1  A: 

For a platform-specific solution, you may be interested in the Win32 function IsBadReadPtr (and others like it). This function will be able to (almost) predict whether you will get a segmentation fault when reading from a particular chunk of memory.

However, this does not protect you in the general case, because the operating system knows nothing of the C runtime heap manager, and if a caller passes in a buffer that isn't as large as you expect, then the rest of the heap block will continue to be readable from an OS perspective.

Greg Hewgill
@Greg - Sorry to say I am not much intrested in WIN32 functions .. if possible a well working dirty hack is also ok since there is NO standard C function
codingfreak
Okay, you didn't specify what platform you *are* interested in. Specifying the platform and compiler may get you a more specific answer.
Greg Hewgill
@Greg - Yeah I agree with you ...
codingfreak
+1  A: 

I always initialize pointers to null value. Therefore when I allocate memory it will change. When I check if memory's been allocated I do pointer != NULL. When I deallocate memory I also set pointer to null. I can't think of any way to tell if there was enough memory allocated.

This doesn't solve your problem, but you got to trust that if someone writes C programs then he is skilled enough to do it right.

Yelonek
@Yelonek .. I do agree with you but I really want to know if there is any possibilty to check ....
codingfreak
+1  A: 

As everyone else said, there isn't a standard way to do it.

So far, no-one else has mentioned 'Writing Solid Code' by Steve Maguire. Although castigated in some quarters, the book has chapters on the subject of memory management, and discusses how, with care and complete control over all memory allocation in the program, you can do as you ask and determine whether a pointer you are given is a valid pointer to dynamically allocated memory. However, if you plan to use third party libraries, you will find that few of them allow you to change the memory allocation routines to your own, which greatly complicates such analysis.

Jonathan Leffler
@Jonathan - What you mean by third party libraries -- ?? I am just using standard libraries and ISO C99. But I will just try out the book which you have recommended.
codingfreak
Third party libraries are anything you didn't write, including the standard libraries. Roughly speaking, if it uses malloc() anywhere, you will have a tough time replacing those calls with your own memory allocator, which means it will be hard to track abuses. You may have to go for more sophisticated memory tracking stuff - check out debugging versions of malloc, valgrind, Purify, etc. (It is the bane of my life - we can't use most libraries from outside without hard work because the product I work on has excruciating memory management requirements that libraries neither know nor care about.)
Jonathan Leffler
A: 

One hack you can try is checking if your pointer points to stack allocated memory. This will not help you in general as the allocated buffer might be to small or the pointer points to some global memory section (.bss, .const, ...).

To perform this hack, you first store the address of the first variable in main(). Later, you can compare this address with the address of a local variable in your specific routine. All addresses between both addresses are located on the stack.

swegi
Yeah ... If I write the whole application I can do that .. But inorder to use a function to check things might be complex ..?
codingfreak
A: 

in general lib users are responsible for input check and verification. You may see ASSERT or something in the lib code and they are used only for debug perpose. it is a standard way when writing C/C++. while so many coders like to do such check and verfying in their lib code very carefully. really "BAD" habits. As stated in IOP/IOD, lib interfaces should be the contracts and make clear what will the lib do and what will not, and what a lib user should do and what should be not necessary.

EffoStaff Effo
A: 

An uninitialised pointer is exactly that - uninitialised. It may point to anything or simply be an invalid address (i.e. one not mapped to physical or virtual memory).

A practical solution is to have a validity signature in the objects pointed to. Create a malloc() wrapper that allocates the requested block size plus the sizeof a signature structure, creates a signature structure at the start of the block but returns the pointer to the location after the signature. You can then create a validation function that takes the pointer, uses a negative offset to get the validity structure and checks it. You will of course need a corresponding free() wrapper to invalidate the block by overwriting the validity signature, and to perform the free from the true start of the allocated block.

As a validity structure, you might use the size of the block and its one's complement. That way you not only have a way of validating the block (XOR the two values and compare to zero), but you also have information about the block size.

Clifford
You might want to check your first sentence: "An initialised pointer is exactly that - uninitialised."
Chris Lutz
Thanks Chris - fixed.
Clifford