-2

I have "segmentation fault" in my code. I'm curious if I allocate some space using "malloc()" in a function. After the function finished, is the space still valid? Further question, when a create a child thread like this, I suppose it exists even after its parent exits. I'm using GCC in Linux.

void foo(){
    void *child_stack;
    child_stack=(void*)malloc(16384);
    child_stack += 16384;
    clone((void*)do_function,child_stack,0,NULL);
}
Musa
  • 96,336
  • 17
  • 118
  • 137
melodrama
  • 265
  • 1
  • 5
  • 14
  • at which point in your code does the segfault occur? (you can figure this out using a debugger, such as gdb) Just using `malloc` should never result in a segfault, you would have to corrupt your processes' memory at some earlier point. – Yefim Dinitz Oct 17 '12 at 19:17
  • You're casting `void *` to `void *`. [That makes no sense.](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) –  Oct 17 '12 at 19:18
  • Further you are doing arithmetic on a `void *`. – Massimiliano Oct 17 '12 at 19:24
  • This code won't even compile on a C compiler... – Lundin Oct 17 '12 at 19:26
  • @YefimDinitz Thanks. Still trying to figure it out. – melodrama Oct 17 '12 at 19:27
  • @Lundin But it did compile. Maybe this way is better. child_stack = (void **) malloc(16384) + 16384 / sizeof(*child_stack); – melodrama Oct 17 '12 at 19:30
  • `child_stack = ((char *)malloc(16384)) + 16384;` – Roddy Oct 17 '12 at 19:35
  • @lundin, except, it does. http://stackoverflow.com/questions/4019671/in-c-can-i-do-arithmetic-on-void-pointers – Roddy Oct 17 '12 at 19:36
  • You cannot take sizeof(*a_void_pointer), that is definitely undefined behavior (C11 6.3.2.2). So it doesn't make any sense to use pointer arithmetic on a void pointer, because there is no way to tell how large a "void" is. – Lundin Oct 17 '12 at 20:14

3 Answers3

2

The main difference between Stack and Heap is when you return from your function call, stuff in stack have been gone, but stuff in heap stays there.

For example, in the following function:

void test_func() 
{
   char a[20];  //using stack
   char *b = malloc(20); //using heap

   strcpy(a, "test string");
   strcpy(b, "test string");

}

after function finished, b still pointing to string, but a is completely gone.

For the second question, the child thread would not be dependent to parent thread unless you using thread_join. However, all threads would be stopped as soon as main process finishes.

Rob W
  • 341,306
  • 83
  • 791
  • 678
Roozbeh Zabihollahi
  • 7,207
  • 45
  • 39
1

To get the cause of the segmentation fault, you can try to compile your code with debug flags (-g) and run it inside the memcheck tool of Valgrind.

Massimiliano
  • 7,842
  • 2
  • 47
  • 62
0
  1. Memory created with malloc goes on the heap, which is available until it is explicitly destroyed with free. That's the main reason to use malloc instead of creating variables on the stack, which are destroyed when they fall out of scope (eg, a function returning) and the stack frame is destroyed. The segfault is probably because you're allocating 16384 bytes, then moving the pointer forward 16384 with the += (why are you doing this?) before passing it to a function that presumably tries to access it.

  2. I'm not 100% sure, but From the wait() man page,

    If a parent process terminates, then its "zombie" children (if any) are adopted by init(8), which automatically performs a wait to remove the zombies.
    
PherricOxide
  • 15,493
  • 3
  • 28
  • 41
  • If I don't free it (because I couldn't figure out how to now), will it cause "segfault"? – melodrama Oct 17 '12 at 19:14
  • 1
    @melodrama, No. The fault's elsewhere. Maybe because childstack + 16384 is actually *outside* the area you've allocated. – Roddy Oct 17 '12 at 19:17
  • @Roddy, I assume stack grows downwards. – melodrama Oct 17 '12 at 19:24
  • @melodrama, malloc returns a pointer to the beginning of the memory that it allocated. It's on the heap, not the stack, and you don't need to increment it in order to use it (all you're doing is moving the pointer to the wrong end of the allocated memory, writing to it then has a segfault because you're accessing memory outside the region malloc allocated). – PherricOxide Oct 17 '12 at 19:26
  • @melodrama, yes, but +16384 is still outside what you malloc'd. Maybe try +16380 instead? – Roddy Oct 17 '12 at 19:29
  • @PherricOxide : clone() requires a pointer to the *end* of some space to use as a stack. He/she maybe out by one, but that's all. – Roddy Oct 17 '12 at 19:30
  • @Roddy, Hm, the man page says "child_stack usually points to the topmost address of the memory", but I've seen several examples online (eg, http://www.morgadinho.org/2006/07/02/clone2/) that just give it the pointer returned from malloc. – PherricOxide Oct 17 '12 at 19:41
  • @PherricOxide according to http://linux.die.net/man/2/clone "Stacks grow downward on all processors that run Linux (except the HP PA processors), so child_stack usually points to the topmost address of the memory space set up for the child stack." – Roddy Oct 17 '12 at 19:45
  • For what it's worth, if you do need to increment the pointer, you need to take into account void* not being 1 byte on some platforms and either cast it to char* before incrementing it or use "ptr += 16384/sizeof(void*);" – PherricOxide Oct 17 '12 at 19:45