I have built a book struct that looks like this:
typedef struct _book{
char name[NAME_LENGTH];
char authors[AUTHORS_NAME_LENGTH];
char publisher[PUBLISHER_NAME_LENGTH];
char genre[GENRE_LENGTH];
int year;
int num_pages;
int copies;
}book;
i'm trying to define a library which is an array of books, so that later on i could deposit books in the library with another function.
had problems with memory write/read when defined the library like this library[BOOK_NUM], so i decided to allocate.
the thing is, it only lets my allocate inside the main function.
when i write this line:
book *library = (book*)malloc(BOOK_NUM*sizeof(book));
outside the main() it gives me an error:
IntelliSense: function call is not allowed in a constant expression
error C2099: initializer is not a constant
but if i move the above line to be inside main() it works. why is that?
also, what is the better way to define the array so that i could change it later with other functions?
You might declare a global or static variable, assuming BOOK_NUM is some #define-d constant (e.g. #define BOOK_NUM 100 somewhere before in your code):
book library[BOOK_NUM];
However, heap allocation is generally preferable, because the resource usage is limited at runtime, not at compile-time or start of execution time.
If BOOK_NUM was extremely big (eg a billion) you could have an issue (program won't be runnable because of lack of memory).
If BOOK_NUM was slightly small (e.g. a dozen) you could have an issue in running some cases (not enough space for books).
If you (wrongly!) declared book library[BOOK_NUM]; as some local variable (e.g. in main), the call frame should be small enough (because the entire call stack is limited to a few mega-bytes, so individual call frames should not exceed a few kilobytes) so BOOK_NUM should be kept small (a few dozens at most).
To quote the GNU coding standards:
4.2 Writing Robust Programs
Avoid arbitrary limits on the length or number of any data structure, including file names, lines, files, and symbols, by allocating all data structures dynamically
So a better way could be to have:
typedef struct book_st {
char* name;
char* authors;
char* publisher;
char* genre;
int year;
int num_pages;
int copies;
} book;
then a "making function" (or "constructing" function) like
/* returns a freshly allocated book to be deleted by delete_book;
the strings arguments should be not null and are duplicated. */
book* make_book(const char*n, const char*a, const char*p,
const char*g, int y, int np, int c) {
assert (n != NULL);
assert (a != NULL);
assert (p != NULL);
assert (g != NULL);
book* b = malloc(sizeof(book));
if (!b) { perror("malloc book"); exit(EXIT_FAILURE); };
memset (b, 0, sizeof(book)); // useless, but safe
char* pname = strdup(n);
if (!pname) { perror("strdup name"); exit(EXIT_FAILURE); };
char* pauth = strdup(a);
if (!pauth) { perror("strdup author"); exit(EXIT_FAILURE); };
char *ppub = strdup(p);
if (!ppub) { perror("strdup publisher"); exit(EXIT_FAILURE); };
char *pgenre = strdup(g);
if (!pgenre) { perror("strdup genre"); exit(EXIT_FAILURE); };
b->name = pname;
b->authors = pauth;
b->publishers = ppub;
b->genre = pgenre;
b->year = y;
b->num_pages = np;
b->copies = c;
return b;
}
Notice that every call to malloc should be tested, because malloc could fail. Here I just exit with some error message; in some cases you would want to recover from malloc failure (e.g. a server might want to continue processing future requests), but that is boringly difficult (you might need to free any unseless malloc-ed pointer so far, etc...).
Of course, you need a destroying or deleting function to release memory, like:
/* destroy and free a book obtained by make_book */
void delete_book(book*b) {
if (!b) return;
free (b->name), b->name = NULL;
free (b->authors), b->authors = NULL;
free (b->publisher), b->publisher = NULL;
free (b->genre), b->genre = NULL;
free (b);
}
Notice my defensive programming style. I am clearing the malloc-ed book pointer before filling it; I am setting to NULL every pointer field in book just after free-ing it. In principle both are useless.
BTW, you could make your library a struct ending with a flexible array member:
struct library_st {
unsigned size; // allocate size
unsigned nbbooks; // actual number of books
book* books[]; // actually, size slots
};
and have functions like struct library_st*make_library(unsigned s); and struct library_st*add_book(struct library_st*lib, book*book); which would return perhaps an updated and reallocated library.
The main thing in C is to document the memory allocation discipline. Every function should say (at least in a comment) who is in charge of freeing pointers and how.
Read much more (at least for concepts and terminology) about virtual address space, C dynamic memory allocation, memory leaks, garbage collection. Notice that reference counting is not a silver bullet.
Consider using Linux as your primary development environment on your laptop. It has good tools (gcc -Wall -g -fsanitize=address with a recent GCC, gdb, valgrind, Boehm's conservative GC ...) and lots of free software whose source code is worth studying to learn more about C programming.
BTW, to store your library on the disk, consider serialization techniques (and textual formats à la JSON), or perhaps sqlite or some real database (PostGreSQL, MongoDB, ...)
You can only call malloc inside a function. main () is a function. You can write other functions. You can't just declare a global variable and initialise it by calling a function.
Related
I am looking for a malloc alternative for c that will only ever be used as a stack. Something more like alloca but not limited in space by the stack size. It is for coding a math algorithm.
I will work with large amounts of memory (possibly hundreds of megabytes in use in the middle of the algorithm)
memory is accessed in a stack-like order. What I mean is that the next memory to be freed is always the memory that was most recently allocated.
would like to be able to run an a variety of systems (Windows and Unix-like)
as an extra, something that can be used with threading, where the stack-like allocate and free order applies just to individual threads. (ie ideally each thread has its own "pool" for memory allocation)
My question is, is there anything like this, or is this something that would be easy to implement?
This sounds like a perfect use for Obstack.
I've never used it myself since the API is really confusing, and I can't dig up an example right now. But it supports all the operations you want, and additionally supports streaming creation of the "current" object.
Edit: whipped up a quick example. The Obstack API shows signs of age, but the principle is sound at least.
You will probably want to look into tuning the align/block settings and likely use obstack_next_free and obstack_object_size if you do any fancy growing.
#include <obstack.h>
#include <stdio.h>
#include <stdlib.h>
void *xmalloc(size_t size)
{
void *rv = malloc(size);
if (rv == NULL)
abort();
return rv;
}
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
const char *cat(struct obstack *obstack_ptr, const char *dir, const char *file)
{
obstack_grow(obstack_ptr, dir, strlen(dir));
obstack_1grow(obstack_ptr, '/');
obstack_grow0(obstack_ptr, file, strlen(file));
return obstack_finish(obstack_ptr);
}
int main()
{
struct obstack main_stack;
obstack_init(&main_stack);
const char *cat1 = cat(&main_stack, "dir1", "file1");
const char *cat2 = cat(&main_stack, "dir1", "file2");
const char *cat3 = cat(&main_stack, "dir2", "file3");
puts(cat1);
puts(cat2);
puts(cat3);
obstack_free(&main_stack, cat2);
// cat2 and cat3 both freed, cat1 still valid
}
As you already found out, as long as it works with malloc you should use it and only come back when you need to squeeze out the last bit of performance.
An idea fit that case: You could use a list of blocks, that you allocate when needed. Using a list makes it possible to eventually swap out data in case you hit the virtual memory limit.
struct block {
size_t size;
void * memory;
struct block * next;
};
struct stacklike {
struct block * top;
void * last_alloc;
};
void * allocate (struct stacklike * a, size_t s) {
// add null check for top
if (a->top->size - (a->next_alloc - a->top->memory) < s + sizeof(size_t)) {
// not enough memory left in top block, allocate new one
struct block * nb = malloc(sizeof(*nb));
nb->next = a->top;
a->top = nb;
nb->memory = malloc(/* some size large enough to hold multiple data entities */);
// also set nb size to that size
a->next_alloc = nb->memory;
}
void * place = a->next_alloc;
a->next_alloc += s;
*((size_t *) a->next_alloc) = s; // store size to be able to free
a->next_alloc += sizeof (size_t);
return place;
}
I hope this shows the general idea, for an actual implementation there's much more to consider.
To swap out stuff you change that to a doubly linked list an keep track of the total allocated bytes. If you hit a limit, write the end to some file.
I have seen a strategy used in an old FORTRAN program that might be what you are looking for. The strategy involves use of a global array that is passed down to each function from main.
char global_buffer[SOME_LARGE_SIZE];
void foo1(char* buffer, ...);
void foo2(char* buffer, ...);
void foo3(char* buffer, ...);
int main()
{
foo1(global_buffer, ....);
}
void foo1(char* buffer, ...)
{
// This function needs to use SIZE1 characters of buffer.
// It can let the functions that it calls use buffer+SIZE1
foo2(buffer+SIZE1, ...);
// When foo2 returns, everything from buffer+SIZE1 is assumed
// to be free for re-use.
}
void foo2(char* buffer, ...)
{
// This function needs to use SIZE2 characters of buffer.
// It can let the functions that it calls use buffer+SIZE2
foo3(buffer+SIZE2, ...);
}
void foo3(char* buffer, ...)
{
// This function needs to use SIZE3 characters of buffer.
// It can let the functions that it calls use buffer+SIZE3
bar1(buffer+SIZE3, ...);
}
I'm pretty new at C programming, and this type of thing keeps popping up. As a simple example, suppose I have a struct http_header with some char pointers:
struct http_header {
char* name;
char* value;
};
I want to fill an http_header where value is the string representation of an int. I "feel" like, semantically, I should be able to write a function that takes in an empty header pointer, a name string, and an int and fills out the header appropriately.
void fill_header(struct http_header *h, char* name, int value)
{
h->name = name;
char *value_str = malloc(100);
sprintf(value_str, "%d", value);
h->value = value_str;
}
int main(int argc, const char * argv[])
{
struct http_header h;
char *name = "Header Name";
int val = 42;
fill_header(&h, name, val);
...
free(h.value);
}
Here, the calling code reads exactly as my intent, but in this case I'm creating the value string dynamically, which means I'd have to free it later. That doesn't smell right to me; it seems like the caller then knows too much about the implementation of fill_header. And in actual implementations it may not be so easy to know what to free: consider filling an array of http_headers where only one of them needed to have its value malloced.
To get around this, I'd have to create the string beforehand:
void fill_header2(struct http_header *h, char* name, char *value_str)
{
h->name = name;
h->value = value_str;
}
int main(int argc, const char * argv[])
{
struct http_header h;
char *name = "Header Name";
int value = 42;
char value_str[100];
sprintf(value_str, "%d", value);
fill_header2(&h, name, value_str);
}
As this pattern continues down the chain of structures with pointers to other structures, I end up doing so much work in top level functions the lower level ones seem hardly worth it. Furthermore, I've essentially sacrificed the "fill a header with an int" idea which I set out to write in the first place. I'm I missing something here? Is there some pattern or design choice that will make my life easier and keep my function calls expressing my intent?
P.S. Thanks to all at Stackoverfow for being the best professor I've ever had.
Well, I would go with the first approach (with a twist), and also provide a destroy function:
struct http_header *make_header(char *name, int value)
{
struct http_header *h = malloc(sizeof *h);
/* ... */
return h;
}
void destroy_header(struct http_header *h)
{
free(h->name);
free(h);
}
This way the caller doesn't have to know anything about http_header.
You might also get away with a version that leaves the main allocation (the struct itself) to the caller and does it's own internal allocation. Then you would have to provide a clear_header which only frees that fill allocated. But this clear_header leaves you with a partially-valid object.
I think your problem is simply that you are programming asymmetrically. You should once and for all decide who is responsible for the string inside your structure. Then you should have two functions, not only one, that should be called something like header_init and header_destroy.
For the init function I'd be a bit more careful. Check for a 0 argument of your pointer, and initialize your DS completely, something like *h = (http_header){ .name = name }. You never know if you or somebody will end up in adding another field to your structure. So by that at least all other fields are initialized with 0.
If you are new at C programming, you might perhaps want to use the Boehm's conservative garbage collector. Boehm's GC works very well in practice, and by using it systematically in your own code you could use GC_malloc instead of malloc and never bother about calling free or GC_free.
Hunting memory leaks in C (or even C++) code is often a headache. There are tools (like valgrind) which can help you, but you could decide to not bother by using Boehm's GC.
Garbage collection (and memory management) is a global property of a program, so if you use Boehm's GC you should decide that early.
The general solution to your problem is that of object ownership, as others have suggested. The simplest solution to your particular problem is, however, to use a char array for value, i.e., char value[12]. 2^32 has 10 decimal digits, +1 for the sign, +1 for the null-terminator.
You should ensure that 1) int is not larger than 32-bits at compile-time, 2) ensure that the value is within some acceptable range (HTTP codes have only 3 digits) before calling sprintf, 3) use snprintf.
So by using a static array you get rid of the ownership problem, AND you use less memory.
I have a question regarding this code. I write this code in my framework, and it caused the framework crashed. But when I rewrite this code below in a single file, but it works just fine. I was just wondering, is the code below is correct for memory allocation and freeing it? (especially for the part of msg->context_var.type = f;)
Thank you
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int value;
int price;
int old;
} type_t;
typedef struct {
type_t *type;
} context_t;
typedef struct {
context_t context_var;
} send_request;
void send_Message(send_request *msg)
{
type_t *f = 0;
f = malloc(sizeof(f));
msg->context_var.type = f;
msg->context_var.type->price = 1;
msg->context_var.type->value = 100;
msg->context_var.type->old =120;
printf("value of %d/n", msg->context_var.type->price);
free(f);
}
int main()
{
send_request *msg = 0;
msg = (send_request *) malloc(sizeof(send_request));
send_Message(msg);
free(msg);
return 0;
}
It's wrong.
f = malloc(sizeof(f)); /* Wrong */
f = malloc(sizeof(*f)); /* Better ? */
sizeof(f) will give you the size of a pointer on your machine; sizeof(*f) will give you the size of the object pointed to.
EDIT As requested by #Perception
When you allocate less than you need you're eliciting Undefined Behavior. Anything can happen (even the desired behavior) and it all depends on the platform, the environment (the moon phase, etc).
msg->context_var.type->value = 100; /* Writes beyond what's allocated. */
So, depending on the memory layout of the "framework" this might simply overwrite some memory and "work", or it could crash. Frankly I prefer when it crashes straight away.
You allocate an instance of context_t on the heap, and then msg->context_var.type gets the value of the resulting pointer f.
Since msg is a pointer parameter to the send_Message function, no reliable assumptions can be made about what is done with msg and its contents after your function exists. As such, when you go on to free the memory pointed to by f, you leave a dangling pointer in msg->context_var.type.
If the memory it points to is accessed after send_Message exists, there's a fair chance that you corrupt something vital (or read something crazy, like a pointer to 0xdeadbeef), as it might contain something completely different now.
Not only are you allocating wrong size (see cnicutar's answer)-- If you are attaching f to message that is passed by the framework, you probably don't want to free it before the function returns. You'll need to free it later, though-- probably through some other facility provided by the framework?
Which is considered better style?
int set_int (int *source) {
*source = 5;
return 0;
}
int main(){
int x;
set_int (&x);
}
OR
int *set_int (void) {
int *temp = NULL;
temp = malloc(sizeof (int));
*temp = 5;
return temp;
}
int main (void) {
int *x = set_int ();
}
Coming for a higher level programming background I gotta say I like the second version more. Any, tips would be very helpful. Still learning C.
Neither.
// "best" style for a function which sets an integer taken by pointer
void set_int(int *p) { *p = 5; }
int i;
set_int(&i);
Or:
// then again, minimise indirection
int an_interesting_int() { return 5; /* well, in real life more work */ }
int i = an_interesting_int();
Just because higher-level programming languages do a lot of allocation under the covers, does not mean that your C code will become easier to write/read/debug if you keep adding more unnecessary allocation :-)
If you do actually need an int allocated with malloc, and to use a pointer to that int, then I'd go with the first one (but bugfixed):
void set_int(int *p) { *p = 5; }
int *x = malloc(sizeof(*x));
if (x == 0) { do something about the error }
set_int(x);
Note that the function set_int is the same either way. It doesn't care where the integer it's setting came from, whether it's on the stack or the heap, who owns it, whether it has existed for a long time or whether it's brand new. So it's flexible. If you then want to also write a function which does two things (allocates something and sets the value) then of course you can, using set_int as a building block, perhaps like this:
int *allocate_and_set_int() {
int *x = malloc(sizeof(*x));
if (x != 0) set_int(x);
return x;
}
In the context of a real app, you can probably think of a better name than allocate_and_set_int...
Some errors:
int main(){
int x*; //should be int* x; or int *x;
set_int(x);
}
Also, you are not allocating any memory in the first code example.
int *x = malloc(sizeof(int));
About the style:
I prefer the first one, because you have less chances of not freeing the memory held by the pointer.
The first one is incorrect (apart from the syntax error) - you're passing an uninitialised pointer to set_int(). The correct call would be:
int main()
{
int x;
set_int(&x);
}
If they're just ints, and it can't fail, then the usual answer would be "neither" - you would usually write that like:
int get_int(void)
{
return 5;
}
int main()
{
int x;
x = get_int();
}
If, however, it's a more complicated aggregate type, then the second version is quite common:
struct somestruct *new_somestruct(int p1, const char *p2)
{
struct somestruct *s = malloc(sizeof *s);
if (s)
{
s->x = 0;
s->j = p1;
s->abc = p2;
}
return s;
}
int main()
{
struct somestruct *foo = new_somestruct(10, "Phil Collins");
free(foo);
return 0;
}
This allows struct somestruct * to be an "opaque pointer", where the complete definition of type struct somestruct isn't known to the calling code. The standard library uses this convention - for example, FILE *.
Definitely go with the first version. Notice that this allowed you to omit a dynamic memory allocation, which is SLOW, and may be a source of bugs, if you forget to later free that memory.
Also, if you decide for some reason to use the second style, notice that you don't need to initialize the pointer to NULL. This value will either way be overwritten by whatever malloc() returns. And if you're out of memory, malloc() will return NULL by itself, without your help :-).
So int *temp = malloc(sizeof(int)); is sufficient.
Memory managing rules usually state that the allocator of a memory block should also deallocate it. This is impossible when you return allocated memory. Therefore, the second should be better.
For a more complex type like a struct, you'll usually end up with a function to initialize it and maybe a function to dispose of it. Allocation and deallocate should be done separately, by you.
C gives you the freedom to allocate memory dynamically or statically, and having a function work only with one of the two modes (which would be the case if you had a function that returned dynamically allocated memory) limits you.
typedef struct
{
int x;
float y;
} foo;
void foo_init(foo* object, int x, float y)
{
object->x = x;
object->y = y;
}
int main()
{
foo myFoo;
foo_init(&foo, 1, 3.1416);
}
In the second one you would need a pointer to a pointer for it to work, and in the first you are not using the return value, though you should.
I tend to prefer the first one, in C, but that depends on what you are actually doing, as I doubt you are doing something this simple.
Keep your code as simple as you need to get it done, the KISS principle is still valid.
It is best not to return a piece of allocated memory from a function if somebody does not know how it works they might not deallocate the memory.
The memory deallocation should be the responsibility of the code allocating the memory.
The first is preferred (assuming the simple syntax bugs are fixed) because it is how you simulate an Out Parameter. However, it's only usable where the caller can arrange for all the space to be allocated to write the value into before the call; when the caller lacks that information, you've got to return a pointer to memory (maybe malloced, maybe from a pool, etc.)
What you are asking more generally is how to return values from a function. It's a great question because it's so hard to get right. What you can learn are some rules of thumb that will stop you making horrid code. Then, read good code until you internalize the different patterns.
Here is my advice:
In general any function that returns a new value should do so via its return statement. This applies for structures, obviously, but also arrays, strings, and integers. Since integers are simple types (they fit into one machine word) you can pass them around directly, not with pointers.
Never pass pointers to integers, it's an anti-pattern. Always pass integers by value.
Learn to group functions by type so that you don't have to learn (or explain) every case separately. A good model is a simple OO one: a _new function that creates an opaque struct and returns a pointer to it; a set of functions that take the pointer to that struct and do stuff with it (set properties, do work); a set of functions that return properties of that struct; a destructor that takes a pointer to the struct and frees it. Hey presto, C becomes much nicer like this.
When you do modify arguments (only structs or arrays), stick to conventions, e.g. stdc libraries always copy from right to left; the OO model I explained would always put the structure pointer first.
Avoid modifying more than one argument in one function. Otherwise you get complex interfaces you can't remember and you eventually get wrong.
Return 0 for success, -1 for errors, when the function does something which might go wrong. In some cases you may have to return -1 for errors, 0 or greater for success.
The standard POSIX APIs are a good template but don't use any kind of class pattern.
Can we check whether a pointer passed to a function is allocated with memory or not in C?
I have wriiten my own function in C which accepts a character pointer - buf [pointer to a buffer] and size - buf_siz [buffer size]. Actually before calling this function user has to create a buffer and allocate it memory of buf_siz.
Since there is a chance that user might forget to do memory allocation and simply pass the pointer to my function I want to check this. So is there any way I can check in my function to see if the pointer passed is really allocated with buf_siz amount of memory .. ??
EDIT1: It seems there is no standard library to check it .. but is there any dirty hack to check it .. ??
EDIT2: I do know that my function will be used by a good C programmer ... But I want to know whether can we check or not .. if we can I would like to hear to it ..
Conclusion: So it is impossible to check if a particular pointer is allocated with memory or not within a function
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.)
The below code is what I have used once to check if some pointer tries to access illegal memory. The mechanism is to induce a SIGSEGV. The SEGV signal was redirected to a private function earlier, which uses longjmp to get back to the program. It is kind of a hack but it works.
The code can be improved (use 'sigaction' instead of 'signal' etc), but it is just to give an idea. Also it is portable to other Unix versions, for Windows I am not sure. Note that the SIGSEGV signal should not be used somewhere else in your program.
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>
jmp_buf jump;
void segv (int sig)
{
longjmp (jump, 1);
}
int memcheck (void *x)
{
volatile char c;
int illegal = 0;
signal (SIGSEGV, segv);
if (!setjmp (jump))
c = *(char *) (x);
else
illegal = 1;
signal (SIGSEGV, SIG_DFL);
return (illegal);
}
int main (int argc, char *argv[])
{
int *i, *j;
i = malloc (1);
if (memcheck (i))
printf ("i points to illegal memory\n");
if (memcheck (j))
printf ("j points to illegal memory\n");
free (i);
return (0);
}
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.
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.
I once used a dirty hack on my 64bit Solaris. In 64bit mode the heap starts at 0x1 0000 0000. By comparing the pointer I could determine if it was a pointer in the data or code segment p < (void*)0x100000000, a pointer in the heap p > (void*)0x100000000 or a pointer in a memory mapped region (intptr_t)p < 0 (mmap returns addresses from the top of the addressable area).
This allowed in my program to hold allocated and memory mapped pointers in the same map, and have my map module free the correct pointers.
But this kind of trick is highly unportable and if your code relies on something like that, it is time to rethink the architecture of your code. You're probably doing something wrong.
I know this is an old question, but almost anything is possible in C. There are a few hackish solutions here already, but a valid way of determining if memory has been properly allocated is to use an oracle to take the place of malloc, calloc, realloc, and free. This is the same way testing frameworks (such as cmocka) can detect memory problems (seg faults, not freeing memory, etc.). You can maintain a list of memory addresses allocated as they are allocated and simply check this list when the user wants to use your function. I implemented something very similar for my own testing framework. Some example code:
typedef struct memory_ref {
void *ptr;
int bytes;
memory_ref *next;
}
memory_ref *HEAD = NULL;
void *__wrap_malloc(size_t bytes) {
if(HEAD == NULL) {
HEAD = __real_malloc(sizeof(memory_ref));
}
void *tmpPtr = __real_malloc(bytes);
memory_ref *previousRef = HEAD;
memory_ref *currentRef = HEAD->next;
while(current != NULL) {
previousRef = currentRef;
currentRef = currentRef->next;
}
memory_ref *newRef = (memory_ref *)__real_malloc(sizeof(memory_ref));
*newRef = (memory_ref){
.ptr = tmpPtr,
.bytes = bytes,
.next = NULL
};
previousRef->next = newRef;
return tmpPtr;
}
You would have similar functions for calloc, realloc, and free, each wrapper prefixed with __wrap_. The real malloc is available through the use of __real_malloc (similar for the other functions you are wrapping). Whenever you want to check if memory is actually allocated, simply iterate over the linked memory_ref list and look for the memory address. If you find it and it's big enough, you know for certain the memory address won't crash your program; otherwise, return an error. In the header file your program uses, you would add these lines:
extern void *__real_malloc (size_t);
extern void *__wrap_malloc (size_t);
extern void *__real_realloc (size_t);
extern void *__wrap_realloc (size_t);
// Declare all the other functions that will be wrapped...
My needs were fairly simple so I implemented a very basic implementation, but you can imagine how this could be extended to have a better tracking system (e.g. create a struct that keeps track of the memory location in addition to the size). Then you simply compile the code with
gcc src_files -o dest_file -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,realloc -Wl,-wrap,free
The disadvantage is the user has to compile their source code with the above directives; however, it's far from the worse I have seen. There is some overhead to allocating and freeing memory, but there is always some overhead when adding security.
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.
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.
Well, I don't know if somebody didn't put it here already or if it will be a possibility in your programme. I was struggling with similar thing in my university project.
I solved it quite simply - In initialization part of main() , after I declared LIST *ptr, I just put that ptr=NULL. Like this -
int main(int argc, char **argv) {
LIST *ptr;
ptr=NULL;
So when allocation fails or your pointer isn't allocated at all, it will be NULL. SO you can simply test it with if.
if (ptr==NULL) {
"THE LIST DOESN'T EXIST"
} else {
"THE LIST MUST EXIST --> SO IT HAS BEEN ALLOCATED"
}
I don't know how your programme is written, but you surely understand what am I trying to point out. If it is possible to check like this your allocation and then pass your arguments to you function, you could have a simple solution.
Of course you must be careful to have your functions with allocating and creating the structure done well but where in C you don't have to be careful.
I don't know a way of doing it from a library call, but on Linux, you can look at /proc/<pid>/numa_maps. It will show all sections of memory and the third column will say "heap" or "stack". You can look at the raw pointer value to see where it lines up.
Example:
00400000 prefer:0 file=/usr/bin/bash mapped=163 mapmax=9 N0=3 N1=160
006dc000 prefer:0 file=/usr/bin/bash anon=1 dirty=1 N0=1
006dd000 prefer:0 file=/usr/bin/bash anon=9 dirty=9 N0=3 N1=6
006e6000 prefer:0 anon=6 dirty=6 N0=2 N1=4
01167000 prefer:0 heap anon=122 dirty=122 N0=25 N1=97
7f39904d2000 prefer:0 anon=1 dirty=1 N0=1
7f39904d3000 prefer:0 file=/usr/lib64/ld-2.17.so anon=1 dirty=1 N0=1
7f39904d4000 prefer:0 file=/usr/lib64/ld-2.17.so anon=1 dirty=1 N1=1
7f39904d5000 prefer:0 anon=1 dirty=1 N0=1
7fffc2d6a000 prefer:0 stack anon=6 dirty=6 N0=3 N1=3
7fffc2dfe000 prefer:0
So pointers that are above 0x01167000 but below 0x7f39904d2000 are located in the heap.
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);
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.
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.
There is a simple way to do this. Whenever you create a pointer, write a wrapper around it. For example, if your programmer uses your library to create a structure.
struct struct_type struct_var;
make sure he allocates memory using your function such as
struct struct_type struct_var = init_struct_type()
if this struct_var contains memory that is dynamically allocated, for ex,
if the definition of struct_type was
typedef struct struct_type {
char *string;
}struct_type;
then in your init_struct_type() function, do this,
init_struct_type()
{
struct struct_type *temp = (struct struct_type*)malloc(sizeof(struct_type));
temp->string = NULL;
return temp;
}
This way,unless he allocates the temp->string to a value, it will remain NULL. You can check in the functions that use this structure, if the string is NULL or not.
One more thing, if the programmer is so bad, that he fails to use your functions, but rather directly accesses unallocated the memory, he doesn't deserve to use your library. Just ensure that your documentation specifies everything.
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.
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.
A pointer tracker, tracks and checks the validity of a pointer
usage:
create memory int * ptr = malloc(sizeof(int) * 10);
add the pointer address to the tracker Ptr(&ptr);
check for failing pointers PtrCheck();
and free all trackers at the end of your code
PtrFree();
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
struct my_ptr_t { void ** ptr; size_t mem; struct my_ptr_t *next, *previous; };
static struct my_ptr_t * ptr = NULL;
void Ptr(void * p){
struct my_ptr_t * tmp = (struct my_ptr_t*) malloc(sizeof(struct my_ptr_t));
printf("\t\tcreating Ptr tracker:");
if(ptr){ ptr->next = tmp; }
tmp->previous = ptr;
ptr = tmp;
ptr->ptr = p;
ptr->mem = **(size_t**) ptr->ptr;
ptr->next = NULL;
printf("%I64x\n", ptr);
};
void PtrFree(void){
if(!ptr){ return; }
/* if ptr->previous == NULL */
if(!ptr->previous){
if(*ptr->ptr){
free(ptr->ptr);
ptr->ptr = NULL;
}
free(ptr);
ptr = NULL;
return;
}
struct my_ptr_t * tmp = ptr;
for(;tmp != NULL; tmp = tmp->previous ){
if(*tmp->ptr){
if(**(size_t**)tmp->ptr == tmp->mem){
free(*tmp->ptr);
*tmp->ptr = NULL;
}
}
free(tmp);
}
return;
};
void PtrCheck(void){
if(!ptr){ return; }
if(!ptr->previous){
if(*(size_t*)ptr->ptr){
if(*ptr->ptr){
if(**(size_t**) ptr->ptr != ptr->mem){
printf("\tpointer %I64x points not to a valid memory address", ptr->mem);
printf(" did you freed the memory and not NULL'ed the pointer or used arthmetric's on pointer %I64x?\n", *ptr->ptr);
return;
}
}
return;
}
return;
}
struct my_ptr_t * tmp = ptr;
for(;tmp->previous != NULL; tmp = tmp->previous){
if(*(size_t*)tmp->ptr){
if(*tmp->ptr){
if(**(size_t**) tmp->ptr != tmp->mem){
printf("\tpointer %I64x points not to a valid memory address", tmp->mem);
printf(" did you freed the memory and not NULL'ed the pointer or used arthmetric's on pointer %I64x?\n", *tmp->ptr); continue;
}
}
continue;
}
}
return;
};
int main(void){
printf("\n\n\t *************** Test ******************** \n\n");
size_t i = 0;
printf("\t *************** create tracker ********************\n");
int * ptr = malloc(sizeof(int) * 10);
Ptr(&ptr);
printf("\t *************** check tracker ********************\n");
PtrCheck();
printf("\t *************** free pointer ********************\n");
free(ptr);
printf("\t *************** check tracker ********************\n");
PtrCheck();
printf("\t *************** set pointer NULL *******************\n");
ptr = NULL;
printf("\t *************** check tracker ********************\n");
PtrCheck();
printf("\t *************** free tracker ********************\n");
PtrFree();
printf("\n\n\t *************** single check done *********** \n\n");
printf("\n\n\t *************** start multiple test *********** \n");
int * ptrs[10];
printf("\t *************** create trackers ********************\n");
for(; i < 10; i++){
ptrs[i] = malloc(sizeof(int) * 10 * i);
Ptr(&ptrs[i]);
}
printf("\t *************** check trackers ********************\n");
PtrCheck();
printf("\t *************** free pointers but set not NULL *****\n");
for(i--; i > 0; i-- ){ free(ptrs[i]); }
printf("\t *************** check trackers ********************\n");
PtrCheck();
printf("\t *************** set pointers NULL *****************\n");
for(i=0; i < 10; i++){ ptrs[i] = NULL; }
printf("\t *************** check trackers ********************\n");
PtrCheck();
printf("\t *************** free trackers ********************\n");
PtrFree();
printf("\tdone");
return 0;
}
I'm not sure how fast msync is, but this is a linux only solution:
// Returns 1 if the ponter is mapped
int pointer_valid (void *p)
{
size_t pg_size = sysconf (_SC_PAGESIZE);
void *pg_start = (void *) ((((size_t)p) / pg_size) * pg_size);
return msync (pg_start, pg_size, MS_ASYNC) == 0;
}
There is almost never "never" in computers. Cross platform is way over anticipated. After 25 years I have worked on hundreds of projects all anticipating cross platform and it never materialized.
Obviously, a variable on the stack, would point to an area on the stack, which is almost linear. Cross platform garbage collectors work, by marking the top or (bottom) of the stack, calling a little function to check if the stack grows upwards or downwards and then checking the stack pointer to know how big the stack is. This is your range. I don't know a machine that doesn't implement a stack this way (either growing up or down.)
You simply check if the address of our object or pointer sits between the top and bottom of the stack. This is how you would know if it is a stack variable.
Too simple. Hey, is it correct c++? No. Is correct important? In 25 years I have seen way more estimation of correct. Well, let's put it this way: If you are hacking, you aren't doing real programming, you are probably just regurigating something that's already been done.
How interesting is that?