I'd like to "override" malloc in pure C with Linux GCC, for memory checking stuffs. Notice that malloc() is a weak symbol, it's OK to do that in pure C. i.e. Making a strong symbol of malloc().
But I just found it crash if calling printf() inside my malloc() implementation, and if removing, it won't crash.
To reproduce:
#include <stdio.h>
extern void *__libc_malloc(size_t size);
static int cnt = 0;
void* malloc(size_t size) {
printf("--- calling customized malloc\n");
cnt += 1;
if(cnt > 1) return NULL;
return __libc_malloc(size);
}
static void leak_test1() {
int* a = malloc(sizeof(int)*5);
a[0] = 3;
}
int main(){
leak_test1();
printf("cnt=%d\n", cnt);
return 0;
}
Does it mean "calling printf is invalid in my own malloc()"? What's the deep reason? (Correct me if I'm wrong)
It is possible that printf call malloc to allocate the buffer for stdout, so you get an infinite recursion.
You might be able to get around this issue by calling fprintf(stderr, ...) as stderr is unbuffered.
Related
My question is regarding freeing allocated memory in different functions. So my code is structured something like this:
int main()
{
// Declare variables
double *val1, *val2;
// Call function 1
function1(&val);
// Call function 2
function2(&val2);
// Do some stuff .....
// Free dynamically allocated memory
free(val1);
free(val2);
// End program
return 0;
}
void function1(double *val1)
{
/* Allocate memory */
val1 = (double*) malloc(n1*sizeof(double));
if (val1 == NULL){
printf("Error: Memory not allocated!");
exit(0);
}
}
void function2(double *val2)
{
// Allocate memory
val2 = (double*) malloc(n2*sizeof(double));
if (val2== NULL){
printf("Error: Memory not allocated!");
// Here I want to free val1!
exit(0);
}
}
Meaning that some memory is allocated for val1 inside function1 and for val2 inside function2.
Now, the contents contained in val1 is not needed in function2, so I would at first sight not have to pass the pointer to val1.
However, if val2 is not allocated correctly I want to exit the program, but free any allocated memory first. Can I free the memory for val1 inside function2 without passing the pointer for val1?
a way to structure functions with dynamic allocation would be to have a return value of an integer, like: int function1(double *val)
that way if it fails you can return a value which would indicate it when the allocation fails, and act accordingly in main()
Can I free the memory for val1 inside function2 without passing the pointer for val1?
No. C language doesn't have a concept of destructors, so commonly used in other languages. In C you have to "pick up the trash" yourself - so if you terminate your program it's nice to free all allocated memory. There are many styles of error handling, choose the one you like. I like kernel coding style. A function that terminates a program in case it fails would be very brutal. A return value that lets the user of the function handle the error case would be nicer and more predictible. It's typical (for me) for C functions to return an int with 0 for success and negative value for failure. Your program could look like this:
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
int function1(double **val1)
{
size_t n1 = 10;
*val1 = (double*) malloc(n1 * sizeof(**val1));
if (*val1 == NULL){
return -ENOMEM;
}
return 0;
}
int function2(double **val2)
{
size_t n2 = 20;
*val2 = malloc(n2 * sizeof(double));
if (*val2== NULL){
return -ENOMEM;
}
return 0;
}
int main()
{
int err = 0;
double *val1, *val2;
err = function1(&val1);
if (err) goto ERROR_function1;
err = function2(&val2);
if (err) goto ERROR_function2;
err = do_some_calc(val1, val2);
free(val2);
ERROR_function2:
free(val1);
ERROR_function1:
return err;
}
Note the error in your program - you were passing double** pointers yet your functions expected double* pointer. Parameters are passed to function by value - values of parameters are copied. To modify a value you have to pass a pointer - that includes pointers, so if you want to modify a pointer you have to pass a pointer to a pointer.
You can write this a lot cleaner & fix some bugs by:
Actually returning a pointer to the allocated memory to the caller. See Dynamic memory access only works inside function.
Leave error handling to the caller.
Leave clean-up to the caller.
This is an artificial example overall, but you could for example do like this:
double function1 (void)
{
return malloc(n1*sizeof(double));
}
double function2 (void)
{
return malloc(n2*sizeof(double));
}
void exit_cleanup (double* v1, double* v2)
{
free(v1);
free(v2);
exit(0);
}
int main (void)
{
double* val1 = NULL;
double* val2 = NULL;
// ...
val1 = function1();
if(val1 == NULL) { exit_cleanup(&v1, &v2); }
// ...
val2 = function2();
if(val2 == NULL) { exit_cleanup(&v1, &v2); }
// Do some stuff .....
exit_cleanup(&v1, &v2);
}
This works because both pointers are initialized to NULL and calling free(NULL) is a safe no-op. All error handling and clean-up has been centralized to a single function. No "on error goto" stuff is necessary.
Another rarely used beast is atexit, which is a standard C function which lets you register a number of functions that will get executed just before program termination. Would have worked just fine here - however, you'd need to make the variables file scope for that case, so it isn't ideal.
You will either have to pass the val1 pointer to function2 or to store val1 globally, both being pretty dirty approaches.
What would be a proper way to approach this issue is to return error codes from both of the functions and handle the errors from main (i.e. free any allocated memory that needs to be free'd).
As a side note, &val1 will have the type double **, not double *. Even though here the might work just fine, it is not correct, and might lead to unexpected behaviour. Your functions would need to be changed like this:
void function1(double **val1)
{
/* Allocate memory */
*val1 = malloc(n1*sizeof(double));
if (*val1 == NULL){
printf("Error: Memory not allocated!");
exit(0);
}
}
This will keep the data types pointer depth properly, and signal you any pointer problem earlier.
I would like a hint on how to complete this puzzle. I need to be able to print what is normally printed out in reverse. Normally this prints, hello there. I need it to print there hello. I am only allowed to add code where it is commented.
Here are some of my thoughts that don't work.
I thought about using the heap to store some data but I can't because stdlib.h is not included.
Can't use goto because I can't add labels and what I would goto is all in one line
Can't use recursion because there are no input parameters and no global variables to modify.
Can't possibly think of a way assembly could help but hey maybe?
I can't do anything obvious like just calling printf's and quitting the program early.
Thoughts on something to do with function pointers? I still don't see how they would help.
#include <stdio.h>
void f1(); void f2(); void f3();
int main() { f1(); printf("\n"); return 0; }
void f1() { f2(); printf(" there "); }
void f2() { f3(); printf(" hello "); }
void f3(){
int x;
//Can add whatever under here
}
I think the only purpose of int x; is to get the stack pointer without using inline assembly.
The solution on how to do this exactly will depend on your platform, the compiler you use and the optimization levels you have used.
I would say first you need to analyze the call stack.
You can do this -
int i;
for (i = 0; i< 10; i++) {
printf ("%p\n", *(void**)((char*) &x - i * 8)); // I am assumming 64 bit machines. If 32 bit replace 8 with 4
}
This will give you the top 10 8 byte values on the stack. Now you need to find the two that look like return addresses. One way to recognize them would be to print the function pointer value of f1 and f2 and see the values close to them.
You now know the indexes where they are stored. Just go ahead and swap them.
For swapping them, say the indices are 12 and 14.
Then you can do this -
*(void**)&x = *((void**)&x + 12);
*((void**)&x + 12) = *((void**)&x + 14);
*((void**)&x + 14) = *(void**)&x;
Also make sure you don't change the stack layout once you get the indices. This means don't remove/add any variables. Don't apply the & operator to any new variables (or remove from any) and don't remove any function calls.
Also another suggestion - Instead of using int x, you could declare another unsigned long long y and use that for the swap instead. Because it would have enough bytes to hold a pointer (on 64 bit machines). Usually there will be padding in case of int x too which should save you from the problem but rather be safe.
Here's an alternate solution that doesn't depend on stack manipulation. The fundamental 'trick' is that the program provides its own implementation of printf() instead of using the standard library's.
Tested on gcc (Mingw, Linux x86 and Linux x64) and MSVC:
#include <stdio.h>
void f1(); void f2(); void f3();
int main() { f1(); printf("\n"); return 0; }
void f1() { f2(); printf(" there "); }
void f2() { f3(); printf(" hello "); }
void f3(){
int x;
//Can add whatever under here
return;
}
void putstr( char const* s)
{
for (;*s;++s) {
putchar(*s);
}
}
int printf(char const* fmt, ...)
{
static char const* pushed_fmt = 0;
if (*fmt == '\n') {
putstr(fmt);
return 0;
}
if (pushed_fmt == 0) {
pushed_fmt = fmt;
return 0;
}
putstr(fmt);
putstr(pushed_fmt);
return 0;
}
I think the idea is that from f3() you have the return addresses on the stack all the way up, and nothing has been printed so far.
You'd have to play with the stack contents so that f3() returns into f1(), which would then return into f2().
Can you take it from here? Depending on the compiler, there will be different ways to accomplish this. Inline assembly might or might not be required.
EDIT: specifically for GCC, see the GCC return address intrinsics.
This should be a portable solution that doesn't mess with the stack and return addresses. Most probably not what was expected by who wrote that challenge, but it's way more fun to think out of the box.
void f3(){
int x;
//Can add whatever under here
static count = 0;
static char buf[256];
if(count==0) {
setvbuf(stdout, buf, _IOFBF, sizeof(buf));
int atexit (void (*func)(void));
atexit(f3);
count = 1;
} else {
const char *src = " there hello \n";
char *dest = buf;
for(; *src;) *dest++ = *src++;
}
}
http://ideone.com/S4zMHP
This works by first using setvbuf to replace the stdout buffer with one that we provide, and switching it to full buffering (instead of line buffering) to make sure that no flush happens before the end of the program (notice that no output has been written yet, so calling setvbuf is legal). We also call atexit to make sure we get called before the end of the program (we don't have stdlib.h, but who needs headers when the required prototypes are already known).
When we are called again (thanks to atexit), the two printf have been called, but the buffer hasn't been flushed yet. We outright replace its content with the string of our interest (which is just as big as what has been written), and return. The subsequent implicit fclose will dump out the modified content of our buffer instead of what was written by the printf.
I'm working on a C project (assignment for school). One of the demands is that in case of malloc() failure, the program must free() all allocated memory and exit().
Consider a case where function A() constructs a linked-list and in each iteration it calls to another function, B(). Now, if a malloc failure occured at B(), it must free() the memory it allocated but function A() should do that as well.
Things are getting quite complicated when you have a tree of function calls larger than two.
In my previous project I used a flag to notify a malloc() failure - if a function uses another function which may use malloc(), it has to check the flag right after. It worked, but code got kinda messy.
Is there a neat solution for this problem?
Of course, with "real" applications all memory is de-allocated by the OS, but I guess this demand is pedagogical..
I think the easiest approach is to create a custom allocator (as somebody already noted in a deleted post) to keep track of all your allocations, then do a custom deallocator, use these for all your heap memory needs.
if a malloc fails you have the list of previously allocated blocks at easy reach.
e.g.
(you need to redo this cause it is not effective and should be optimized but shows the principle and only ocular compilation)
typedef struct
{
void* pMemory; /* for the allocated memory */
size_t size; /* for better debugging */
} MemoryBlock;
#define MAXBLOCKS 1000
MemoryBlock myheap[MAXBLOCKS]; // global so zero:ed
static int block = 0;
void* myalloc(size_t size)
{
static int block = 0;
// you should check vs MAXBLOCKS
myheap[block].pMemory = malloc(size);
myheap[block].size = size;
// check if it failed.
if ( myheap[block].pMemory == NULL )
{
for (int i = 0; i < block; ++i)
{
myfree(myheap[i].pMemory);
}
fprintf( stderr, "out of memory\n");
exit(EXIT_FAILURE);
}
else
{
return myheap[block++].pMemory;
}
}
void myfree(void* p)
{
for (int i = 0; i < block; ++i)
{
if ( p == myheap[i].pMemory )
{
free(myheap[i].pMemory);
myheap[i].pMemory = NULL;
return;
}
}
}
Yes. The best (and conventional) way is to initialize every pointer value to zero. Then set it during the malloc() assignment. Ex: myPtr = malloc( 10 );
It will be zero in case of failure, and you check that. And finally, when you go about freeing, you always check the pointer value before calling free():
if ( myPtr != 0 )
free( myPtr );
There is no need for an extra flag.
Are you having issue checking for errors or handling them? If you want info on catching them, use donjuedo's suggestion.
For ideas on freeing memory in the event of error, try one of these two methods:
1) For a uni-directional linked-list, keep a special pointer that points to the head of the list. In your cascading free function, start at the head, capture the next-pointer in a temp variable, free the head, move to the next structure in the list using the temp-pointer, and repeat the process until the next-pointer == 0.
2) For a bi-directional linked-list (my preference) you don't need to keep a special pointer to the head of the list. Assuming you are still at the tail, just capture the previous-pointer into a temp variable, free the tail, move back using the temp-pointer, and repeat the process until the previous-pointer == 0
You could look into the atexit() function, to register code that will be executed when the program terminates. Such code can then check if there is anything that needs to be free()d.
Note that atexit() has no way to unregister. So you need to make sure that you register each cleanup function only once, and that it does the right thing when there is nothing to clean up.
#include <stdlib.h>
#include <stdio.h>
int *ptr1;
char *ptr2;
int clean1_registered, clean2_registered;
void clean1(void)
{
printf("clean1 called\n");
if (ptr1) {
free(ptr1);
ptr1 = NULL;
}
}
void clean2(void)
{
printf("clean2 called\n");
if (ptr2) {
free(ptr2);
ptr2 = NULL;
}
}
void B(void)
{
ptr2 = malloc(100);
if (!clean2_registered) {
atexit(clean2);
}
}
void A(void)
{
ptr1 = malloc(100 * sizeof(int));
if (!clean1_registered) {
atexit(clean1);
}
B();
}
int main(int argc, char **argv)
{
A();
}
When I execute this code, I'm receiving a "segmentation error (core dumbed)".
#include <pthread.h>
#include <stdio.h>
void function(char *oz){
char *y;
y = (char*)oz;
**y="asd";
return NULL;
}
int main(){
char *oz="oz\n";
pthread_t thread1;
if(pthread_create(&thread1,NULL,function,(void *)oz)){
fprintf(stderr, "Error creating thread\n");
return 1;
}
if(pthread_join(thread1,NULL)){
fprintf(stderr, "Error joining thread\n");
return 2;
}
printf("%s",oz);
return 0;
}
First you need to decide, how you want to manage the memory: is the memory allocated by caller, or inside the thread function.
If the memory is allocated by caller, then the thread function will look like:
void *function(void *arg)
{
char *p = arg;
strcpy(p, "abc"); // p points to memory area allocated by thread creator
return NULL;
}
Usage:
char data[10] = "oz"; // allocate 10 bytes and initialize them with 'oz'
...
pthread_create(&thread1,NULL,function,data);
If the memory is allocated inside the thread function, then you need to pass pointer-to-pointer:
void *function(void *arg)
{
char **p = (char**)arg;
*p = strdup("abc"); // equivalent of malloc + strcpy
return NULL;
}
Usage:
char *data = "oz"; // data can point even to read-only area
...
pthread_create(&thread1,NULL,function,&data); // pass pointer to variable
...
free(data); // after data is not needed - free memory-
Your compiler might be warning you about some of these problems. Don't ignore compiler warnings! Warnings are the way your compiler tells you "Hold on! I don't quite understand this bit of code... Please put it in a language I understand!". Which book are you reading? I see other problems, which I won't mention in this question, arising from this approach. It's not safe to learn C by "trial and error", or by "misguided example" (eg. copying/pasting and modifying). You should be reading a book written by a professor who teaches programming for a living, and has a bloody good reputation for doing so. Please answer this question before reading any further.
pthread_create expects a function pointer that indicates a function with a signature like this:
void *function(void *argument);
The function pointer you're giving it will be converted to a function pointer that assumes that signature. pthread_create will then try to use that function pointer, the only way it knows how... This is undefined behaviour. ... and besides, as indicated by #AdamRosenfield, you can't return values from a function that returns void. This ought to be causing your compiler to spew errors and warnings at you. Your function should look like:
void *function(void *oz) {
/* ... */
}
In the block comment is another series of lies in your question. Your code doesn't segfault, because it doesn't compile. y is a char *... *y is a char... **y is a compiler error. I would assume that you only meant to dereference it once, but then assigning "asd" to a char makes no sense, either, so I must assume you meant to declare y as char **y;. You seem to be using typecasts superfluously. Learn about them before you use them, so that you don't misuse them or use them in places where you don't need to (such as trying to convert a char * to a char *... wtf?).
void *function(void *oz) {
char **y = oz;
*y = "asd";
}
Hence, you should probably be passing pthread_open a char ** value, too. It makes no sense to pass a char * value and then treat it as though it's a char ** value, right? There's no need to cast any pointer to object to a void *; That conversion is one of the automatic ones.
if (pthread_create(&thread1, NULL, function, &oz)){
fprintf(stderr, "Error creating thread\n");
return 1;
}
I am trying to create a function that allocates memory of a certain specified size. In the main, I create the pointer and then send the pointer and the size to the function for memory to be allocated. For some reason it causes all sorts of problems. My program works smoothly if I use the malloc in the main, but not through the function.
int main(void){
int * pointer;
int array_size = SIZE;
...
allocate_memory(&pointer,array_size);
...
free(pointer);
}
allocate_memory(int *pointer,int size){
*pointer = (int *)malloc(size*sizeof(int));
if(!(*pointer)){
printf("Memory allocation fail!");
exit(0);
}
The problem now is that it gives me an error when I try to free the memory.
I would appreciate it if the solution will come with a short explanation. I am starting to be very confused about how these pointers and castings are working.
Thanks in advance!
There were many errors in your program which I am pointing out:
You need to #define the macro SIZE as otherwise the program just won't know what it is.
It's better to declare a prototype of the function allocate_memory() so that any discrepancy in type of arguments or return type is detected
You had passed &pointer as an argument to allocate_array() in main().For this it is necessary to define the function as allocate_memory(int **pointer,int size) instead of allocate_memory(int *pointer,int size) which you have done.
if(*pointer==NULL) implements the condition in a much simpler way and serves just the same purpose.
Use exit(1) for unsuccessful termination as exit(0) is used to denote successful termination.
Never ignore warnings.It's not a good practice.
Here's the corrected code.It compiles well without warnings and does the job (memory allocation) as intended.
#include<stdio.h>
#include<stdlib.h>
#define SIZE 30
void allocate_memory(int**,int);
int main(void){
int * pointer;
int array_size = SIZE;
allocate_memory(&pointer,array_size);
free(pointer);
}
void allocate_memory(int **pointer,int size)
{
*pointer = malloc(size*sizeof(int));
if(*pointer==NULL)
{
printf("Memory allocation fail!");
exit(1);
}
else
printf("\nMemory allocation successful");
}