validate pointer that was returned from malloc

B

Bryan Bullard

Hi,

Is there a standard way to validate if a pointer points to memory that was
allocated by malloc?


TIA
 
K

Kristofer Pettijohn

Is there a standard way to validate if a pointer points to memory that was
allocated by malloc?

You would have to write your own wrapper for malloc for that one - that
might be fun. :)

Kristofer
 
F

Flash Gordon

You would have to write your own wrapper for malloc for that one -
that might be fun. :)

This is still not guaranteed.

#include <stdlib.h>
#include <my_wrappers.h>

void foo(void)
{
char *ptr = my_malloc(5) /* allocated memory at address 0x1000 */
free(ptr); /* Oops, the wrong free was used */
ptr = my_malloc(5) /* allocated memory address is 0x0FFF, don't ask
why, it's just a screwy allocator */
ptr++;
my_print_valid(ptr); /* my_print_valid thinks this is object
returned by first my_malloc call, but it is really 1 byte in to memory
returned by second my_malloc call */
}

So it only works if your wrappers are always used, not if someone
forgets once.
 
E

E. Robert Tisdale

Bryan said:
Is there a standard way
No.

to validate if a pointer points to memory that was allocated by malloc?
> cat onStack.c
#include <stdio.h>
#include <stdlib.h>

int onStack(void* p) {
return (p > (void*)&p);
}

int main(int argc, char* argv[]) {
char c;
char* p = &c;
//char* p = (char*)malloc(sizeof(char));
if (onStack(p)) {
fprintf(stdout,
"p probably points to a character in automatic storage.\n");
}
else {
fprintf(stdout,
"p probably points to static data or free storage.\n");
}
return 0;
}
 
B

Bryan Bullard

E. Robert Tisdale said:
Bryan said:
Is there a standard way
No.

to validate if a pointer points to memory that was allocated by malloc?
cat onStack.c
#include <stdio.h>
#include <stdlib.h>

int onStack(void* p) {
return (p > (void*)&p);
}

int main(int argc, char* argv[]) {
char c;
char* p = &c;
//char* p = (char*)malloc(sizeof(char));
if (onStack(p)) {
fprintf(stdout,
"p probably points to a character in automatic storage.\n");
}
else {
fprintf(stdout,
"p probably points to static data or free storage.\n");
}
return 0;
}

Actually, what I'm looking for is a way to determine if a pointer points to
a block that is "safe" to read.
 
E

Eric Sosman

Bryan said:
Bryan said:
Is there a standard way
[...]

Actually, what I'm looking for is a way to determine if a pointer points to
a block that is "safe" to read.

And you've been told that there's no standard way, which
is what you asked for. I've got a counter-question: If your
code is handed a junk pointer, what corrective action do you
expect it to take?
 
M

Mark McIntyre

Actually, what I'm looking for is a way to determine if a pointer points to
a block that is "safe" to read.

There is still no standard way to do this. If the block points to memory
you didn't allocate, thats a coding error. If it points to memory you
deallocated, thats also a coding error. If it points to corrupted memory,
your programme is already dead, so its too late to worry...
 
B

Bryan Bullard

I've got a counter-question: If your
code is handed a junk pointer, what corrective action do you
expect it to take?

Something more graceful then core dump.
 
M

Mark McIntyre

Something more graceful then core dump.

Then you're out of luck. There's no standard way to detect memory
corruption.

The question you should probably be asking is "why would I ever get a bad
pointer, if I wrote my code carefully?"


Of course from a system-specific point of view there might be either a
coding hack of some sort or a 3rd party library which trapped bad memory
and handled it. That would be a topic for a unix or windows or whatever
programming group.
 
E

E. Robert Tisdale

Bryan said:
Actually, what I'm looking for is a way to determine
if a pointer points to a block that is "safe" to read.

No.

It isn't "safe" to "read" from any uninitialized memory
whether allocated from the automatic of free storage.
If you use malloc to allocate free storage,
you need to initialize (write to) that storage
before you can read it. If you are worried about
a [non NULL] pointer to an invalid object,
about the only thing that you can do is write
a known valid bit pattern into some field of that object
that you can check before you attempt access the other fields:

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct X {
unsigned
int pattern;
int other;
} X;

inline static
X X_create(int i) {
X x;
x.pattern = 0x55555555;
x.other = i;
return x;
}

inline static
void X_destroy(const X* p) {
X* q = (X*)p;
q->pattern = 0xAAAAAAAA;
}

inline static
bool X_valid(const X* p) {
return 0x55555555 == p->pattern;
}

inline static
int X_value(const X* p) {
return p->other;
}

int main(int argc, char* argv[]) {
X* p = (X*)malloc(sizeof(X));
*p = X X_create(13)
if (X_valid(p))
fprintf(stdout, "X_value(p) = %d\n", X_valid(p));
X_destroy(p);
free((void*)p);
return 0;
}
 
B

Bryan Bullard

....
If you are worried about
a [non NULL] pointer to an invalid object,
about the only thing that you can do is write
a known valid bit pattern into some field of that object
that you can check before you attempt access the other fields:

This is essentially what I've done. However, I would like to make sure that
the pointer is accessible before I check the pattern in the structure that
is pointed to. This is my issue.

....
 
E

Eric Sosman

Bryan said:
Something more graceful then core dump.

That's not very specific, is it?

I posed the question because a core dump is usually
the best and most desirable outcome in a case like this.
Consider: There's not much corrective action you can
safely take, because there's no reason to believe the
bad pointer you've detected is the first bad pointer
the program has used. It may well have scribbled all
over memory before you had a chance to notice, and it
would be perilous to proceed on the basis of information
already known to be suspect. All you know is that the
program has gone off the rails, and badly -- a hard stop
will at least prevent the amok program from doing further
damage to disk files and the like, and a hard stop with
a core dump to facilitate post-mortem analysis is usually
welcome.

<off-topic>

A similar situation arises in multi-threaded programs,
where people are always asking how to respond to SIGSEGV
by terminating "only the offending thread" instead of the
entire process. Usually, they haven't really thought
about the situation.

</off-topic>

... and that's why I asked the question: to see if
you'd actually thought it through, and if so what you
expected to do about error recovery. "Something more
graceful than a core dump" doesn't give me a warm fuzzy
feeling about how much thought you've given the matter,
although I could be wrong about that. What are your
intentions?
 
E

E. Robert Tisdale

Bryan said:
E. Robert Tisdale said:
If you are worried about
a [non NULL] pointer to an invalid object,
about the only thing that you can do is write
a known valid bit pattern into some field of that object
that you can check before you attempt access the other fields:

This is essentially what I've done.
However, I would like to make sure that the pointer is accessible
before I check the pattern in the structure that is pointed to.

You can't.
This is my issue.

You might look into installing a signal handler
to handle Invalid memory reference (SIGSEGV).
But these are *not* really topical in comp.lang.c
so try a newsgroup specific to your operating system
and try your local documentation:

man 7 signal

for example.
 
K

Keith Thompson

Bryan Bullard said:
And what would that fact be?

The fact that the pointer points to memory that was allocated by
malloc. (Presumably you also want to remember whether it's been
passed to free(), and deal with calloc() and realloc().)

There is no portable way to do what you want other than by carefully
keep track of everything yourself. Sorry if that's an unsatisfactory
answer, but it's the way it is.
 
M

Mark McIntyre

And what would that fact be?

That the memory was allocated by malloc.

Chuck means "remember that you allocated it, and you will have no problem
with its validity"
 
M

Mark McIntyre

...
If you are worried about
a [non NULL] pointer to an invalid object,
about the only thing that you can do is write
a known valid bit pattern into some field of that object
that you can check before you attempt access the other fields:

This is essentially what I've done. However, I would like to make sure that
the pointer is accessible before I check the pattern in the structure that
is pointed to. This is my issue.

ERT's method isn't guaranteed anyway. All bitpatterns could represent valid
memory, or some could be traps or otherwise invalid. F'rexample setting
uninitialised pointers to 0xFFFFF or 0xDEADBEEF might seem good, but both
might be valid addresses.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top