views:

778

answers:

9

Hello, I have a very basic question and need help. I am trying to understand what is the scope of a dynamically allocated memory (on heap).

#include <stdio.h>
#include <malloc.h>

//-----Struct def-------
struct node {
     int x;
     int y;
};

//------GLOBAL DATA------

//-----FUNC DEFINITION----
void funct(){
  t->x = 5; //**can I access 't' allocated on heap in main over here ?**
  t->y = 6; //**can I access 't' allocated on heap in main over here ?**
  printf ("int x = %d\n", t->x);
  printf ("int y = %d\n", t->y);
  return;
}

//-----MAIN FUNCTION------
int main(void){
      struct node * t = NULL;// and what difference will it make if I define 
                                 //it outside main() instead- as a global pointer variable
          t = (struct node *) malloc (sizeof(struct node));
      t->x = 7;
      t->y = 12;
      printf ("int x = %d\n", t->x);
      printf ("int y = %d\n", t->y);

    funct(); // FUNCTION CALLED**
    return 0;
}

So, here can I access structure 't' in funct() even though the memory is allocated in main() without passing argument (pointer to t to function funct) - since heap is common to a thread ? And what difference will it make if I define struct node * t = NULL outside of main() as a global variable and is there anything wrong with it ? Thanks

+1  A: 

In your code 't' is a local variable of main() - it cannot be accessed from anywhere else. This has nothing to do with threading. Please correct your code.

anon
+3  A: 

No, you will not be able to access t like that because even though in main you made t point to something on the heap, which is globally accessible, the variable t itself is a pointer which is local to main (and located on the stack).

Ferruccio
The fact that the pointer is allocated on the stack isn't relevant to the discussion. Stack variables can easily be accessed by other threads as well.
wekempf
Was this a multi-threading question? I didn't get a sense that it was. I thought it was purely about scope.
Ferruccio
+3  A: 

To access a variable the function needs to know the address of this variable - the value of "t" pointer. So you must pass it into the function, otherwise the function will have no means to know what to access.

You could as well declare a global variable pinter "t" and use it from any function but again explicitly.

sharptooth
+2  A: 

The memory allocated can be accessed, but that's not your problem. The variable 't' is visible only within main, because that's where you declared it. Those are two different concepts that you'll need to understand. The storage for data is not the same thing as the variable that refers to it.

wekempf
+1  A: 

No, you would need to make t global, or pass the pointer to funct(), I'd recommend doing the second. Right now, t is in the scope of main() only.

You might also consider adding a mutex to the structure, if you plan on having several threads operating on t at once. If you do that, also consider mlock() to ensure the structure is not paged out, or locks get slow.

Tim Post
+8  A: 

When you use malloc(), the memory returned by that can be accessed anywhere in your code, assuming that you can see the variable which has the pointer returned by malloc().

So in your code, if t was global, it would be visible in main and in funct(), and yes, you could use it in both.

As it is, as previous answers have mentioned, funct() has no idea what t is, because the declaration and definition of t are in main; t is out of scope in funct. The memory you've allocated onto t would be useable in funct, if funct knew what t was.

Blank Xavier
+1  A: 

Just change your function to accept the pointer to that memory.

/* changing the variable name to make it clear that p is scoped to funct() */
/* when it's passed, just as t is local to main() */
void funct(struct node *p){
p->x = 5;
p->y = 6;
printf ("int x = %d\n", p->x);
printf ("int y = %d\n", p->y);
return;
}

...

funct(t);

/* now free the memory you allocated */
free(t);
return 0;

This is the whole point of allocating memory on the heap - automatic (stack) variables are limited to the scope of the block you declare them in. Heap memory is available anywhere - you just need to pass a pointer so that other functions know where to find what you stored.

Mitch Flax
+1  A: 

The accepted answer is a little misleading.

When you use malloc(), the memory returned by that can be accessed anywhere in your code, assuming that you can see the variable which has the pointer returned by malloc().

This is equally true of any memory allocated in C or C++, whether heap, stack or static. Just put & in front of a local variable, and you now have the key that allows any other part of the program to get at the storage for that variable, and use it just as effectively as if they could see the variable name itself.

Local variable names are only visible inside the scope they are declared in, but their storage is accessible from anywhere, in any thread, assuming the address has been taken and passed around.

It dangerous, and yet frequently necessary, to take the address of local variables in C/C++, and so it is unfortunately impossible to use those languages effectively without understanding this.

Daniel Earwicker
A: 

as t is a pointer to the structure defined in the function main. you cannot have an access to it in funct(). Make t global so that it can be accessed in the funct() or pass the pointer as a argument to funct(). making it global is not the best choice. In a multithreaded environment muiltiple threads may try to access it so u need to have some kind of locking mechanism to avoid access at the same time. adding the locking it functionality may lead to other overhead so the best choice should be to pass it as the argument.