Linked List & Dynamic Memory Allocation

Hi,

I am learning about data structures.  I am somewhat confused and
unable to apply concept of dynamic memory allocation to my
application.  This is what I am trying to do.  I have an array of
structures as follows:

#define MAX 3

typdef struct node
{
    char name[30];
    struct node* next;
}nodes;

int main (void)
{
    nodes m_node[MAX];

   // play around with link list here add, remove, search items etc.

   return 0;

}

I am trying to dynamically allocate memory if user chooses to enter
more than 3 records.  I run following code to allocate memory
dynamically.  Code is running fine.

nodes* pNewRec = (nodes *) malloc(sizeof(nodes));
if (!pNewRec)
{
    printf("Unable to allocate memory\n");
    exit(1);
}

I want to attach this new chunk of memory back to my original
m_node[MAX] array and then print all the records/items in linked
list.  That is now m_node array has 4 records (one was created
dynamically).  I am unable to attach new record entry to m_node. Need
help.  Thanks

0
8/27/2007 6:19:57 PM
vc.mfc 33608 articles. 0 followers. Follow

19 Replies
515 Views

Similar Articles

[PageSpeed] 48

First of all, none of the code you've provided makes a linked list, only an 
array.

If you have three nodes declared as you have, you could make them into a 
linked list like this:

for (int i = 0; i < (MAX - 1); i++)
    m_nMode[i].next = &m_nMode[i+1];
m_nMode[MAX-1].next = NULL;

Although it seems kind of pointless given that these items are already in an 
array. Also, the m_ prefix is generally used to identify a variable as a 
class member variable, which your is not. That's a little confusing.

You could then add your new node to the list like this:

   m_nMode[MAX-1].next = pNewRec;
   pNewRec->next = NULL;

But you need to be careful here. Some of this linked list is declared on the 
stack and will dissappear as soon as your function returns, while one node 
in the list was allocated from the heap and will not dissappear until you 
pass it's address to free.

You can print all records this way:

for (nodes *p = m_nMode; p != NULL; i = p->next)
     // print record pointed to by p

-- 
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message 
news:1188238797.773199.307270@w3g2000hsg.googlegroups.com...
> Hi,
>
> I am learning about data structures.  I am somewhat confused and
> unable to apply concept of dynamic memory allocation to my
> application.  This is what I am trying to do.  I have an array of
> structures as follows:
>
> #define MAX 3
>
> typdef struct node
> {
>    char name[30];
>    struct node* next;
> }nodes;
>
> int main (void)
> {
>    nodes m_node[MAX];
>
>   // play around with link list here add, remove, search items etc.
>
>   return 0;
>
> }
>
> I am trying to dynamically allocate memory if user chooses to enter
> more than 3 records.  I run following code to allocate memory
> dynamically.  Code is running fine.
>
> nodes* pNewRec = (nodes *) malloc(sizeof(nodes));
> if (!pNewRec)
> {
>    printf("Unable to allocate memory\n");
>    exit(1);
> }
>
> I want to attach this new chunk of memory back to my original
> m_node[MAX] array and then print all the records/items in linked
> list.  That is now m_node array has 4 records (one was created
> dynamically).  I am unable to attach new record entry to m_node. Need
> help.  Thanks
> 

0
jwood (1292)
8/27/2007 6:51:10 PM
Sorry for confusion.  I deliberately left code out because it was
irrelevant to the question I am asking. I have program working-I have
a linked list and it prints all the records fine.  The only problem is
connecting/attaching a new dynamically allocated records to the linked
list.

Will this work if user enters 5 or 6 or even 100  or x number of
records?  Your code worked for adding on only 1 more record.  It keeps
the 3 hardcoded records then added one more with the help of following
lines of code:

m_nMode[MAX-1].next = pNewRec;
   pNewRec->next = NULL;

However, if user enters more than 1 the only one attached to the list
is the very last entry that user made before choosing to stop.  Still
need help.  Thanks

0
8/27/2007 7:12:25 PM
The code below couldn't possible work for adding addition nodes. For 
starters, it works by setting the next member of the MAX-1 element of that 
array, which won't be the last item any more.

Ideally, you should store a reference to the first and last item in the 
list. Ideally, you would stick all of that in a class. Then you can appended 
items like this:

void AppendNode(node *pNode)
{
    if (m_pHead == NULL)
        m_pHead = m_pTail = pNode;
    else
    {
        m_pTail->next = pNode;
        m_pTail = pNode;
    }
    pNode->next = NULL;
}

-- 
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message 
news:1188241945.675725.326960@r29g2000hsg.googlegroups.com...
> Sorry for confusion.  I deliberately left code out because it was
> irrelevant to the question I am asking. I have program working-I have
> a linked list and it prints all the records fine.  The only problem is
> connecting/attaching a new dynamically allocated records to the linked
> list.
>
> Will this work if user enters 5 or 6 or even 100  or x number of
> records?  Your code worked for adding on only 1 more record.  It keeps
> the 3 hardcoded records then added one more with the help of following
> lines of code:
>
> m_nMode[MAX-1].next = pNewRec;
>   pNewRec->next = NULL;
>
> However, if user enters more than 1 the only one attached to the list
> is the very last entry that user made before choosing to stop.  Still
> need help.  Thanks
> 

0
jwood (1292)
8/27/2007 8:10:42 PM

one-trick-pony wrote:
> Sorry for confusion.  I deliberately left code out because it was
> irrelevant to the question I am asking. I have program working-I have
> a linked list and it prints all the records fine.  The only problem is
> connecting/attaching a new dynamically allocated records to the linked
> list.
> 
> Will this work if user enters 5 or 6 or even 100  or x number of
> records?  Your code worked for adding on only 1 more record.  It keeps
> the 3 hardcoded records then added one more with the help of following
> lines of code:
> 
> m_nMode[MAX-1].next = pNewRec;
>    pNewRec->next = NULL;
> 
> However, if user enters more than 1 the only one attached to the list
> is the very last entry that user made before choosing to stop.  Still
> need help.  Thanks

Is this purely an exercise? If not, there are tools in the STL to make 
your life easier.

But if it is...

First, I wouldn't call a node, 'nodes'. Your starting array is a list of 
'nodes'.

	Node nodes[3];

So you have the array populated and the last node has a node pointer of 
null or the next one on the heap. You can walk the pointers to find the 
last node.

Node* pNode;
for( pNode= nodes[ 3 ].next; pNode->next; pNode= pNode->next )
    ;

pNode->next= new Node;

Or you can just keep a pointer to the last node that you update when you 
add nodes, like:

pNode= pNode->next;

Use this pNode to setup your new node and keep it around to add the next 
node.

But for an occasional TCHAR array, I don't think I've used an array on 
the stack for a decade. (I'm really thinking here! :)

Best, Dan.

0
public21 (290)
8/27/2007 8:21:30 PM
This is purely an excercise....all identifiers are dummy which I made
on the fly.  Should've chosen some meaningful names.  It is a C based
program. No C++ so no new operator :o)  I could have written this in C+
+ but I am doing this excercise for two reasons

1. learn legacy C code
2. data structures










0
8/27/2007 9:01:54 PM

one-trick-pony wrote:

> This is purely an excercise....all identifiers are dummy which I made
> on the fly.  Should've chosen some meaningful names.  It is a C based
> program. No C++ so no new operator :o)  I could have written this in C+
> + but I am doing this excercise for two reasons
> 
> 1. learn legacy C code

For the most part c++ is an extension of c. (There are a few subtle 
differences that I can't remember now.) If you know c++ you know c.

> 2. data structures

I take it you have the structure stuff down ok but it looks like you 
want to handle them on the stack and the heap. At that, you are 
extending the exercise to a linked list. So, where are you since 
Jonathan's and my last post?

Best, Dan.

0
public21 (290)
8/27/2007 10:01:40 PM
Interesting point.  When I code in C/C++ I choose not to think about
stack and heap.  I focus on code than worry about the deep down
details of what is happening.  I would like to learn that sometime but
my current goal is to learn the language and manipulating data
structures etc.  Both of you mentioned stack and heap in this
example.  I am not sure where that fits into the picture.  I know, for
instance, when I call malloc it uses heap to allocate memory.  But I
don't care  where and how it gets memory as long as I get memory
allocated for my program.  Surely, I would like to learn these
concepts. I am interested if you can shed light into this.

Like I mentioned, this is an excercise, I have a very simple program.
There is only main routine-no functions.  However, it seems I have to
be careful when I call other functions and manipulate linked list
because then stack becomes involved. I am not sure how will that
effect my program.

The last thing I tried was the first reponse from Jonathan Wood in an
attempt to append items to a linked list.

m_nMode[MAX-1].next = pNewRec;
   pNewRec->next = NULL;


It worked by allowing me to attach only 1 item.  However, I want the
ability to keep on attaching items until user chooses to quit.  I have
a loop that asks user after every entry whether they want to continue
or not.  Inside that loop I have this line of code:

nodes* pNewRec = (nodes *) malloc(sizeof(nodes));


My struggle is achieving attachment of new records into existing array
of structures.  That is array, nodes m_node[MAX];
 should  expand to accomadate new records.  I hope you understand what
I am trying to do.  Thanks for tips.  I am learning.  Again, please
tell me about stack and heap and how it can effect my program.
Thanks.


0
8/27/2007 10:32:00 PM

one-trick-pony wrote:

> Interesting point.  When I code in C/C++ I choose not to think about
> stack and heap.  I focus on code than worry about the deep down
> details of what is happening.  I would like to learn that sometime but
> my current goal is to learn the language and manipulating data
> structures etc.  Both of you mentioned stack and heap in this
> example.  I am not sure where that fits into the picture.  I know, for
> instance, when I call malloc it uses heap to allocate memory.  But I
> don't care  where and how it gets memory as long as I get memory
> allocated for my program.

Actually, in c++ it is your job to know about the memory, there really 
is no way out of it. You will have to move to managed if you don't want 
to know. (I'm not a .net programer so I don't really know what you do 
need to know.)

To wit, stack memory is managed. You don't have to worry about where it 
comes from but you do have to know it is only available 'in scope'.
Meaning, when you write:

{ //beginning of scope

    int i; The memory now available for 'i'.

} //end of scope and the memory for i doesn't exist and no problems as 
the compiler won't let you use 'i' from here. But, if you have an 
integer pointer object that lives beyond this scope and you had:

int* pInt;

{
    int i;
    pInt= &i;
}
*pInt= 123; //This is broken code.

As for the heap, both malloc and new do the same thing. And you 
absolutely have to manage this memory yourself. For every new object you 
must have a corresponding delete object or you will have a memory leak. 
Or worse, you run out of memory.

> Like I mentioned, this is an excercise, I have a very simple program.
> There is only main routine-no functions.  However, it seems I have to
> be careful when I call other functions and manipulate linked list
> because then stack becomes involved. I am not sure how will that
> effect my program.

Maybe the above addresses your concern here.

> The last thing I tried was the first reponse from Jonathan Wood in an
> attempt to append items to a linked list.
> 
> m_nMode[MAX-1].next = pNewRec;
>    pNewRec->next = NULL;
> 
> 
> It worked by allowing me to attach only 1 item.

That is because the last item you added is not on the stack so you can't 
use m_nMode[MAX-1] directly to keep adding. Go back to where I talked 
about walking pointers. At that, I think you have too much on your plate 
by having three items on the stack and the rest on the heap.

Start with a node pointer:
Node* nodebase= new Node;
node->next= NULL;

nodebase is your starting place. Now keep a second pointer for last 
inserted. They are the same with one item in the list.

Node* nodepos= nodebase;

Add another node:
nodepos->next= new Node;
nodepos= nodepos->next;
nodepos->next= NULL;

And when you are done with this memory extend the 'walk pointers' code I 
posted to delete or free the nodes. You can do the above with 
malloc/free or new/delete. Same code otherwise.

Best, Dan.

0
public21 (290)
8/27/2007 11:14:25 PM
one-trick-pony,

> Like I mentioned, this is an excercise, I have a very simple program.
> There is only main routine-no functions.  However, it seems I have to
> be careful when I call other functions and manipulate linked list
> because then stack becomes involved. I am not sure how will that
> effect my program.

If you read my response to you carefully, I mentioned what the primary 
difference was between the two forms of memory.

> It worked by allowing me to attach only 1 item.  However, I want the
> ability to keep on attaching items until user chooses to quit.  I have
> a loop that asks user after every entry whether they want to continue
> or not.  Inside that loop I have this line of code:

I answered that as well.

-- 
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

0
jwood (1292)
8/27/2007 11:31:04 PM
Hi,

Think of stack being defined at compile time.
Think of heap being undefined at compile time and defined at run-time.

SomeFunc()
{
char arrayStack[100]; <- Compiler knows. Stack
char* arrayHeap =3D new char[Some_Calculated_Value];  <- Compiler does =
not know. Heap.

delete [] arrayStack;  /* Error.  It is automatically deleted */
delete [] arrayHeap;   /* Correct . You must take care of deleting =
objects created with new or malloc. */
}

HTH,
"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message =
news:1188253920.562326.312270@19g2000hsx.googlegroups.com...
> Interesting point.  When I code in C/C++ I choose not to think about
> stack and heap.  I focus on code than worry about the deep down
> details of what is happening.  I would like to learn that sometime but
> my current goal is to learn the language and manipulating data
> structures etc.  Both of you mentioned stack and heap in this
> example.  I am not sure where that fits into the picture.  I know, for
> instance, when I call malloc it uses heap to allocate memory.  But I
> don't care  where and how it gets memory as long as I get memory
> allocated for my program.  Surely, I would like to learn these
> concepts. I am interested if you can shed light into this.
>=20
> Like I mentioned, this is an excercise, I have a very simple program.
> There is only main routine-no functions.  However, it seems I have to
> be careful when I call other functions and manipulate linked list
> because then stack becomes involved. I am not sure how will that
> effect my program.
>=20
> The last thing I tried was the first reponse from Jonathan Wood in an
> attempt to append items to a linked list.
>=20
> m_nMode[MAX-1].next =3D pNewRec;
>   pNewRec->next =3D NULL;
>=20
>=20
> It worked by allowing me to attach only 1 item.  However, I want the
> ability to keep on attaching items until user chooses to quit.  I have
> a loop that asks user after every entry whether they want to continue
> or not.  Inside that loop I have this line of code:
>=20
> nodes* pNewRec =3D (nodes *) malloc(sizeof(nodes));
>=20
>=20
> My struggle is achieving attachment of new records into existing array
> of structures.  That is array, nodes m_node[MAX];
> should  expand to accomadate new records.  I hope you understand what
> I am trying to do.  Thanks for tips.  I am learning.  Again, please
> tell me about stack and heap and how it can effect my program.
> Thanks.
>=20
>
0
Nobody530 (222)
8/27/2007 11:33:00 PM
You can't write in C or C++ without understanding the role of the stack and the heap.

Here's an exercise in linked-lists

class Cell {
     public:  // constructor
        Element(double v)  { next = NULL; value = v; }
     public:  // structural members
        Element * next;
     public:
         double value;  // or whatever you want to link together
};

Cell * ListHead = NULL;

void AddToHeadOfList(double x)
    {
     Cell * C = new Cell(x);
     C->next = ListHead;
     ListHead = C;
    }

void AddToTailOfList(double x)
    {
     Cell * C = new Cell(x);
     if(ListHead == NULL)
        { /* empty list */
         ListHead = C;
         return;
        } /* empty list */
     Cell * p = ListHead;
     while(p->next != NULL)
       { /* find last */
        p = p->next;
       } /* find last */
     p->next = C;
    }

1. Now write the same problem as a non-circular two-way linked list with a prev pointer,
and then write a circular list, where ListHead->prev points to the last element of the
list.  

2. Write a queue based on the above structure which allows immediate append to the tail in
constant time independent of the size of the queue (hint: you need two pointers, qHead and
qTail, to achieve this).

3. Write code that can remove any element from the list, for the three forms
(singly-linked, doubly-linked, doubly-linked circular)

4. Write code that will insert an element in sorted order.

5. Bonus points: Take a list that is unsorted and sort it in n log n time (not n**2)

6. Bonus points: write code that can insert an element into a sorted list with thousands
of entries in a time that is guaranteed to always exceed the expected average performance
of O(n/2).  Hint: you need additional data structures to make this work well.

7. Bonus points: Write code that will handle the fact that the list is being accessed from
more than one concurrent thread.  Use CRITICAL_SECTION

8. Bonus points: Write code that will use the queue as a means of interthread
communication (requires mutexes and semaphores) [hint: see my essay on semaphores]

9. Serious bonus points: Write code that tries to recover from lockups, and undue delays.

10. Now rewrite all of the examples to use a fixed-size array of elements as the sole
source of all instances (no more malloc/new allowed!)

11. Very serious bonus points: put this array in shared memory.  Use based pointers to
handle the list pointers (at this point you've done the Thursday lab in my Systems
Programming course).

Note that while C++ using MFC, STL, boost, etc. make it easy to build link lists, none of
them can handle 11 very well, and it really is important to understand the underlying
mechanisms.  Also handy when things start going bad, to understand the underlying
mechanisms.

Once you've done 10, you undertand how storage allocators work.  The rest is just
engineering (making them fast, for example).  You can also see my essay on how storage
allocators work, on my MVP Tips site.
				joe

On Mon, 27 Aug 2007 15:32:00 -0700, one-trick-pony <worldofpain.aamir@gmail.com> wrote:

>Interesting point.  When I code in C/C++ I choose not to think about
>stack and heap.  I focus on code than worry about the deep down
>details of what is happening.  I would like to learn that sometime but
>my current goal is to learn the language and manipulating data
>structures etc.  Both of you mentioned stack and heap in this
>example.  I am not sure where that fits into the picture.  I know, for
>instance, when I call malloc it uses heap to allocate memory.  But I
>don't care  where and how it gets memory as long as I get memory
>allocated for my program.  Surely, I would like to learn these
>concepts. I am interested if you can shed light into this.
>
>Like I mentioned, this is an excercise, I have a very simple program.
>There is only main routine-no functions.  However, it seems I have to
>be careful when I call other functions and manipulate linked list
>because then stack becomes involved. I am not sure how will that
>effect my program.
>
>The last thing I tried was the first reponse from Jonathan Wood in an
>attempt to append items to a linked list.
>
>m_nMode[MAX-1].next = pNewRec;
>   pNewRec->next = NULL;
>
>
>It worked by allowing me to attach only 1 item.  However, I want the
>ability to keep on attaching items until user chooses to quit.  I have
>a loop that asks user after every entry whether they want to continue
>or not.  Inside that loop I have this line of code:
>
>nodes* pNewRec = (nodes *) malloc(sizeof(nodes));
>
>
>My struggle is achieving attachment of new records into existing array
>of structures.  That is array, nodes m_node[MAX];
> should  expand to accomadate new records.  I hope you understand what
>I am trying to do.  Thanks for tips.  I am learning.  Again, please
>tell me about stack and heap and how it can effect my program.
>Thanks.
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15975)
8/27/2007 11:43:54 PM
I know about that approach.  In the book I have, the author is using
what you have described. I wanted to do something different-an attempt
at learning something.  Best way is to actually practice it. I
understand what you meant by stack and heap.  I just learned it in
different vocabulary.  The books I have talked about "scope" which is
now I see linked with stack.  For instance,


void dummy(int i)
{
  i=4; //this i exists only in this routine
}
int main(void)
{
   int i =0; <this i exists only here
   dummy(i);
   return 0;
}

I understand the scope rules in above example.  I knew stack is
invovled when calling functions. Now I know that my array is on stack
but the last item which I added is on heap.  Wonderful!  Other than
that I already have example in the book that is doing this in C.
Last question is when malloc is used to allocate memory in a program
and a free function is not called, will OS do the "clean up" after
process is done executing and will it always lurk in the memory if OS
does not do clean up?  It is a very simple program, I did forget to
include free call.  Program seems to be running fine even with a
missing free call.  Is memory in the back being filled and if I run
this program large number of times, it will end of exhausting system
resources?  That is, its execution time is very tiny.  User can quit
immediately or be there forever entering records.  I guess if this
program runs long enough it will surely exhaust system memory.  What
if it is executed then exited , then executed and then exited over and
over.  Does it still have potential to bring system to its knees or
every time process ends, OS reclaims resources used by this process?

Thanks for help.  I learned another way of thinking.

0
8/27/2007 11:59:28 PM

one-trick-pony wrote:

> I understand the scope rules in above example.  I knew stack is
> invovled when calling functions. Now I know that my array is on stack
> but the last item which I added is on heap.  Wonderful!  Other than
> that I already have example in the book that is doing this in C.
> Last question is when malloc is used to allocate memory in a program
> and a free function is not called, will OS do the "clean up" after
> process is done executing and will it always lurk in the memory if OS
> does not do clean up?

The memory goes away with termination. But if you want to do it right 
you will learn to manage your memory. A 'tiny' leak is no excuse for 
writing sloppy code. It is pretty simple in your case:

for( pNode= firstnode; pNode; )
{
    Node* pTmp= pNode;
    pNode= pNode->next;
    delete pTmp;
}


Best, Dan.

0
public21 (290)
8/28/2007 12:24:08 AM
see below...
On Mon, 27 Aug 2007 16:33:00 -0700, "Nobody" <Nobody@yahoo.com> wrote:

>Hi,
>
>Think of stack being defined at compile time.
>Think of heap being undefined at compile time and defined at run-time.
****
Not true.  The stack is allocated dynamically at runtime.  The "allocation" consists of a
subtract instruction from the ESP, or by a push instruction, but it is nonetheless
allocation.  It no more exists at compile time than the heap.  It is dynamically freed
when it is no longer needed; this is accomplised in a variety of ways, from pop
instructions to the standard exit protocol which restores the ESP from the EBP.  The stack
is not "defined" at runtime.  In essence, you think of the stack as a memory resource
which is being dynamically allocated at runtime using a highly-efficient allocator.  In
effect, the local variables of the stack can be thought of as a synthetic 'struct' or
'class' whose instance is created dynamically at runtime. The instance of the record which
defines the parameters to a function and the local variables is known as the "stack
frame".
****
>
>SomeFunc()
>{
>char arrayStack[100]; <- Compiler knows. Stack
****
This is not allocated until SomeFunc is called.  When SomeFunc is called, its code will
allocate the array on the stack.  If SomeFunc is called again recursively, another array
is allocated on the stack.  If you do this often enough you will run out of stack space.

All the compiler knows at compile time is that it has to, at runtime, call the stack
allocator to allocate that array.  Now, "calling the stack allocator" is very easy, it is
a single instruction (see, in my example below, the instruciton labeled [5]).  But
conceptually, there is an explicit salloc/sfree done (that's stack-alloc, and stack-free)
done for every function call.  (Note that in the IBM/360 environment, the stack was
actually allocated by a genuine, authentic, malloc-equivalent on function entry and a
genuine, free-equivalent, on function return, making function calls in IBM's PL/1
*incredibly* expensive!).

For example, let's consider the function shown below:

int factorial(int n)
    {
     char arrayStack[100];
     if(n == 1)
       return 1;     
     return n * factorial(n - 1);
    }

Call this with n==1 and you will allocate 100 bytes of stack space for the array.  Call it
with n==2 and there will be 200 bytes of stack space allocated.  Call it with n==3 and you
will get 300 bytes of stack space allocated.  When the third incarnation of the function
returns, 100 bytes are released, when the second incarnation of the function returns,
another 100 bytes are released, and finally, the last 100 bytes are released.

It actually needs 112 bytes for each call.  However, here's actual code:

//****************************************************************
// In main(), we call factorial(5)
//****************************************************************
; 17   : 	factorial(5);

  00033	6a 05		 push	 5          *** Allocate Stack Space [1]
  00035	e8 00 00 00 00	 call	 ?factorial@@YAHH@Z	; factorial  *** Allocate Stack
Space [2]
  0003a	83 c4 04	 add	 esp, 4                 *** Allocate Stack Space [3]

//****************************************************************
// Here's factorial
//****************************************************************
_n$ = 8	

?factorial@@YAHH@Z PROC NEAR				; factorial
; 7    :     {
  00000	55		 push	 ebp             *** Alocate stack space  [4]
  00001	8b ec		 mov	 ebp, esp               *** [4.1]
  00003	83 ec 68	 sub	 esp, 104    ; 00000068H  *** Allocate stack space [5]
; 8    :      char data[100];
; 9    :      if(n == 1)
  00006	83 7d 08 01	 cmp	 DWORD PTR _n$[ebp], 1
  0000a	75 07		 jne	 SHORT $L9622
; 10   :          return 1;
  0000c	b8 01 00 00 00	 mov	 eax, 1
  00011	eb 13		 jmp	 SHORT $L9620
$L9622:
; 11   :      else
; 12   :          return n * factorial(n - 1);
  00013	8b 45 08	 mov	 eax, DWORD PTR _n$[ebp]
  00016	83 e8 01	 sub	 eax, 1
  00019	50		 push	 eax                 *** Allocate stack space [6]
  0001a	e8 00 00 00 00	 call	 ?factorial@@YAHH@Z	*** Allocate stack space [7]
  0001f	83 c4 04	 add	 esp, 4                   *** Deallocate stack space [8]
  00022	0f af 45 08	 imul	 eax, DWORD PTR _n$[ebp]
$L9620:
; 13   :     }
  00026	8b e5		 mov	 esp, ebp           *** Deallocate stack space [9]
  00028	5d		 pop	 ebp                    *** Deallocate stack space [10]
  00029	c3		 ret	 0                        *** Deallocate stack space [11]

[1] we allocate a single integer-valued element on the stack, initializing it to 5.  This
    holds the parameter being passed in.
[2] we allocate a single pointer-sized element on the stack, initializing it to the return
address.
    transfer control to the subroutine.

Control now goes to the subroutine factorial()

[4] we allocate a single pointer-sized element on the stack, initializing it to hold the
previous
    value of EBP, the "frame pointer".  
[4.1] Having saved the old frame pointer, we initialize EBP to point to the current
top-of-stack
    Positive offsets from EBP will name parameters, negative offsets from EBP will name
local variables
[5] Allocate 104 bytes on the stack 100 bytes reprsent the array.  The remaining 4 are
apparently
    so that the local allocation will be a multiple of 8 bytes (100 is not an even
multiple
    of 8)
[6] allocate a single integer-valued element on the stack, to hold the parameter for the
next call
[7] allocate a single pointer-sized element on the stack, initializing it to the return
address
    transfer control to the subroutine
[8] deallocate the space allocated in step [6]
[9] deallocate all the 104 bytes allocated on the stack for the local storage
[10] deallocate the stack space allocated in step [4], and restore the EBP to its previous
value
[11] deallocate the pointer-sized value which holds the return address, and transfer
control
     back to the calling site

control now resumes following the call instruction at the calling site

[3] deallocate the stack space allocated in [1]

Since you're trying to understand the role of the stack, I suggest studying this example
until you really understand what is going on.

To create a similar example, generate a combined-source-and-code-bytes listing, generate a
release mode version of the program, and set the parameters in the settings to 
Optimization
        Optimization:           Disable (/Od)
Code Generation
        Buffer Security Checks: No
Output files
        Assembler output:       Assembly, Machine Code, and Source (/FAcs)

Try many examples of your own.  See what happens if you try to compute factorial(10000).
Then try the same computation without the 100-byte array and see how large a value of
factorial you can compute.  Stack space is most definitely allocated dynamically at
runtime, not at compile time.  
					joe
 
>char* arrayHeap = new char[Some_Calculated_Value];  <- Compiler does not know. Heap.
>
>delete [] arrayStack;  /* Error.  It is automatically deleted */
>delete [] arrayHeap;   /* Correct . You must take care of deleting objects created with new or malloc. */
>}
>
>HTH,
>"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message news:1188253920.562326.312270@19g2000hsx.googlegroups.com...
>> Interesting point.  When I code in C/C++ I choose not to think about
>> stack and heap.  I focus on code than worry about the deep down
>> details of what is happening.  I would like to learn that sometime but
>> my current goal is to learn the language and manipulating data
>> structures etc.  Both of you mentioned stack and heap in this
>> example.  I am not sure where that fits into the picture.  I know, for
>> instance, when I call malloc it uses heap to allocate memory.  But I
>> don't care  where and how it gets memory as long as I get memory
>> allocated for my program.  Surely, I would like to learn these
>> concepts. I am interested if you can shed light into this.
>> 
>> Like I mentioned, this is an excercise, I have a very simple program.
>> There is only main routine-no functions.  However, it seems I have to
>> be careful when I call other functions and manipulate linked list
>> because then stack becomes involved. I am not sure how will that
>> effect my program.
>> 
>> The last thing I tried was the first reponse from Jonathan Wood in an
>> attempt to append items to a linked list.
>> 
>> m_nMode[MAX-1].next = pNewRec;
>>   pNewRec->next = NULL;
>> 
>> 
>> It worked by allowing me to attach only 1 item.  However, I want the
>> ability to keep on attaching items until user chooses to quit.  I have
>> a loop that asks user after every entry whether they want to continue
>> or not.  Inside that loop I have this line of code:
>> 
>> nodes* pNewRec = (nodes *) malloc(sizeof(nodes));
>> 
>> 
>> My struggle is achieving attachment of new records into existing array
>> of structures.  That is array, nodes m_node[MAX];
>> should  expand to accomadate new records.  I hope you understand what
>> I am trying to do.  Thanks for tips.  I am learning.  Again, please
>> tell me about stack and heap and how it can effect my program.
>> Thanks.
>> 
>>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15975)
8/28/2007 1:23:55 AM
Greetings,

I have everything working now.  Thanks for your tips, suggestions and
guidance.  I have better understanding of how programs relate to stack
and heap.  I have created a singly linked list with dynamic memory
allocation enabled.  Next task is doubly linked list but I've got a
good handle on that.  One last question with this topic is, what
happens when memory allocated with malloc is not freed with free?  I
am not seeing an immediate disaster when I deliberately leave out call
to free. And with every new record/item for which memory is allocated
do I need to call free( ) for every single memory allocation call or
just once?  Thanks.

0
8/28/2007 1:44:53 PM
"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message 
news:1188308693.475853.46210@d55g2000hsg.googlegroups.com...
> Greetings,
>
> I have everything working now.  Thanks for your tips, suggestions and
> guidance.  I have better understanding of how programs relate to stack
> and heap.  I have created a singly linked list with dynamic memory
> allocation enabled.  Next task is doubly linked list but I've got a
> good handle on that.  One last question with this topic is, what
> happens when memory allocated with malloc is not freed with free?

This would be what is called a memory leak.  The allocated memory is not 
available for reuse.  After a while your applicaation will get an "out of 
memory" error.  This is especially of concern in applications that are 
intended to run for days and days: They are pretty much guaranteed to fail 
unless the memory bookkeeping is very meticulous.

> I
> am not seeing an immediate disaster when I deliberately leave out call
> to free. And with every new record/item for which memory is allocated
> do I need to call free( ) for every single memory allocation call or
> just once?  Thanks.
>

You need to call free() for every single malloc() allocation.  It is kind of 
like borrowing a book from the library: You must return it! 

0
Scott
8/28/2007 2:27:05 PM
Well, you have a memory leak.  That is, once you have allocated the memory, it is no
longer available for use except for the purpose it was allocated for.  If you neglect to
call free, that storage will not be available any longer.  There won;t be an immediate
disaster, but eventually your program will call malloc and will get NULL returned, because
there's no more memory available.  Now, if you are actually *using* all that memory,
you've gone one problem, because it means your program needs more memory than is
available.  But if you didn't need that memory any longer, but simply forgot to delete it,
then your program is considered erroneous.

You must call free() for every pointer you got via malloc().

Consider the following

for(int i = 0; i < 1000000; i++)
    { /* create a picture */
     Picture * p = malloc(100000);
     ...fill in p->bitmap;
     p->next = PictureList;
     PictureList->next = p;
   } /* create a picture */

Suppose you needed a million pictures.  You'll probably run out of space.  So you would
actually have to write
      Picture * p = malloc(100000);
      if(p == NULL)
        { /* out of picture space */
         ... report that you only had enough room for 
         ... i pictures, and can't fill in any more
         break;
        } * out of picture space */
      .. fill in p->bitmap;

This is a legitimate case where you may need more memory than actually is available.

However, this is a bug:

for(int i = 0; i < 100000; i++)
    {
     Thing * = (Thing *)malloc(sizeof(Thing));
     ... deal with error
     ... deal with Thing
     ThingLIst->next = Thing;
    } 

Now, having created 100,000 Things, you do whatever you want to do with the list, then
come back and do

void ProcessThings()
   {
    Thing * ThingList;
    ThingList->next = NULL;

    for(...)
       ... the loop above...

    ...process all the things
    return;
   }

Now note what happened.  The only reference to those 100,000 Thing objects is in that
local variable.  You return from the function.  All 100,000 Things remain allocated, and
there's no way to find out where they are!  That storage is now lost forever (or for as
long as the program runs, until it exits).

So the correct approach is then to do

      while(ThingList->next != NULL)
          { /* free them up */
           Thing * nextthing = ThingList->next->next;
           free(ThingList->next);
           ThingList->next = nextthing;
          } /* free them up */
      return;

So you have to iterate down the list and free up each value.  Now, note that you could NOT
write this as

      while(ThingList->next != NULL)
          { /* buggy */
           free(ThingList->next);
           ThingList->next = ThingList->next->next;
          } /* buggy */

Why?  Because as soon as you do the free(), the storage occupied is now available for
allocation.  So an attempt to use the pointer in the next statement is using storage that
has already been freed!  (In the debug build, the debug runtime actually overwrites the
contents of the storage block on free(), thus destroying the pointer.  In a multithreaded
app, just as you return from free, another thread might come in, do a malloc(), and
reallocate that storage for its own purposes, so by the time you get arround to using the
pointer you freed, the storage it points to has already been modified for another purpose
and is not available).

There are three serious errors you can make using dynamic allocation:
	Failing to free storage you no longer need (storage leak)
	Using a pointer to storage you have already freed (dangling pointer)
	Freeing the same storage twice (double free)
The debug runtime looks for all three of these errors and reports them via assertion
failures in the library.  The storage leak will be reported when the program exits.

Note that if you have something like

	struct Thing {
	      Thing * next;
	      LPCTSTR name;
                };

and you've done
	Thing * p = (Thing *)malloc(sizeof(Thing));
                 p->name = (LPCTSTR)malloc(_tcslen(InputString) + 1);
	_tcscpy(p->name, InputString);
                ... add Thing to list of Things

then
	Thing * p = ...get a thing somehow
	free(p);
will free the Thing, but *not* the string pointed to by p->name!  So the way to free an
object is to do
	free(p->name);
	free(p);

Now this can be handled in C++ by destructors:

	struct Thing {
	       Thing()  { name = NULL; }
                       ~Thing() { delete [] name; }
                       void AddName(LPCTSTR n) { delete [] name; 
                                name = new TCHAR[_tcslen(n) + 1];
                                _tcscpy(name, n);
                              }
                 };


So you can write
	Thing * p = new Thing;
	... use it
	p->AddName(InputName);
	delete p;

and when you call delete, the storage you explicitly allocated will be freed when ~Thing
is called (note that you have to use new/delete on Things, rather than malloc/free)

Now note that objects like CString handle the implicit deallocation automatically, so if
you do
	struct Thing {
	      Thing() {}
	      CString name;
                      void AddName(LPCTSTR n) { name = n; }
                };

then when you do
	Thing * t = new Thing;
	t->AddName(InputString);
	...
	delete t;

The delete will call destructors on all the objects (but not pointers-to-objects) in the
class/struct, so the space pointed to by the CString is freed when ~CString is called. And
that's the whole point of C++ as far as storage management: you don't need to worry about
deallocating things that you set up to be automatically deallocated. 
 
				joe

On Tue, 28 Aug 2007 06:44:53 -0700, one-trick-pony <worldofpain.aamir@gmail.com> wrote:

>Greetings,
>
>I have everything working now.  Thanks for your tips, suggestions and
>guidance.  I have better understanding of how programs relate to stack
>and heap.  I have created a singly linked list with dynamic memory
>allocation enabled.  Next task is doubly linked list but I've got a
>good handle on that.  One last question with this topic is, what
>happens when memory allocated with malloc is not freed with free?  I
>am not seeing an immediate disaster when I deliberately leave out call
>to free. And with every new record/item for which memory is allocated
>do I need to call free( ) for every single memory allocation call or
>just once?  Thanks.
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15975)
8/28/2007 3:52:44 PM
I think my book has an error.  Code is allocating memory with malloc
and I don't see a free call to match it.

void enterdata()
{
    struct address *info;

    for( ; ; )
    {
        info = (struct address *)malloc(sizeof(struct address));
        // check here to see if memory was allocated

        gets(info->name);
        // if user enters null break out of for loop
        gets(info->location);

        // call another function here to create a link list in sorted
order(sorting based on name)

    }
}

void printlist()
{
   // print all the data user has entered
}

I don't see a free call anywhere.  You guys mentioned to put free call
for every call to malloc but when I do that inside the for loop I end
up losing my data and when I try to print the list program crashes.  I
guess my question is where to put the free call?  And how would I know
how many times user entered data to match the number of malloc calls?
My guess is because it is only one pointer that is using malloc.  By
calling free(info) will reclaim memory for ALL the malloc calls made.
But the only thing throwing me off is you guys mentioned free for
every malloc.  Please help.

0
8/29/2007 1:13:59 PM
"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message 
news:1188393239.299777.238780@g4g2000hsf.googlegroups.com...
>I think my book has an error.  Code is allocating memory with malloc
> and I don't see a free call to match it.
>
> void enterdata()
> {
>    struct address *info;
>
>    for( ; ; )
>    {
>        info = (struct address *)malloc(sizeof(struct address));
>        // check here to see if memory was allocated
>
>        gets(info->name);
>        // if user enters null break out of for loop
>        gets(info->location);
>
>        // call another function here to create a link list in sorted
> order(sorting based on name)
>
>    }
> }
>
> void printlist()
> {
>   // print all the data user has entered
> }
>
> I don't see a free call anywhere.  You guys mentioned to put free call
> for every call to malloc but when I do that inside the for loop I end
> up losing my data and when I try to print the list program crashes.  I
> guess my question is where to put the free call?  And how would I know
> how many times user entered data to match the number of malloc calls?
> My guess is because it is only one pointer that is using malloc.  By
> calling free(info) will reclaim memory for ALL the malloc calls made.
> But the only thing throwing me off is you guys mentioned free for
> every malloc.  Please help.
>

To decide where to put the free calls you have to know when the data is no 
longer needed.  It is possible that the data is needed throughout the life 
of the program, in which case you would find some place where the program is 
closing down (such as just before main() returns).

For a structure such as your linked list you would write a loop that steps 
through the structure, extracts each pointer to an info, then does free() 
with that pointer.

It is possible your book did not bother to do this.  If the allocations are 
not freed at end-of-program then the operating system does reclaim the 
memory after your program has exited.  However, this is rather bad practice. 
The debugging environment is capable of detecting such "memory leaks" in a 
debug build, and leaving things allocated at the end defeats this helpful 
tool.

0
Scott
8/29/2007 2:52:40 PM
Reply:

Similar Artilces:

custom entity + linking contact
Hi, I am new to the CRM product. And have a few questions...... I know that in 3.0 you can create custom entity, but can you link your custom entity to other entity such as contact/account? In defining the custom entity, there's a relationship field and mapping field. What are they exactly? When/How do you define a relationship/mapping? Thanks, Jane You can create relationships to other entities when you create a new custom entity in 3.0. I believe that you can also establish if the new custom entity maps up to an existing entity, or receives mapped info from an existing entity. -...

Deleting "mail to:" email address links
I have a relativly straight forward spreadsheet where I am maintaining a large address list. It contains a homeowner's lot number, name, address, telephone #, and e- mail address. When attempting to select random cells for data entry/modification, I receive and automated message " mailto: (a random e-mail address) - click once to follow. Click and hold to select this cell." I have no idea where/how this message/feature/function is being attached to these cells but would like to eliminate it. Since seeing these messages, the size of the worksheet has been increasing in ...

Outlook 2003 Imap Auto Purge wish list
I hope someone at Microsoft can code in a auto purge Imap deleted email function into there next Service Pack. I can see a problem rolling this out to our employees. There going to delete messages and those messages are going to stay on the Email server until they do a Purge. I'm afraid they just won't do this. We use Imap. No auto purge means emails staying on the server which over time just takes up hard drive space and makes tape backups take longer. wayne Hi Wayne, You should send suggestions to mswish@microsoft.com as the newsgroups are not monitored for feature request...

OWA Error for http links
links inside a message body always generate an asp redirect code that does not execute at all thus giving an http 500 error - page not found. Example on a link to http://www.nightlight.org within a mail body. http://orange/exchweb/bin/redir.asp? URL=http://www.nightlight.org/ Exchange Server 2003 running on Server 2000 SP4 PLease help. ...

Linking Basic Beancounting spreadsheets?
I am new to Excel (and this forum) & want to make my own General Ledger, Monthy Synopsis, Trial Balances, Financial Statements etc. for a new business. I am reading _Basic_Beancounting_ by T. James Cook and wish to use Excel efficiently. (Just learned how to group tabs to make multiple identical forms. Works great and saves a pile of time!) Now I want to take the debit & credit totals from each account column in the monthly synopsis sheet and link them (automatically post) them to the appropriate column in their individual running totals of each General Ledger Account. The problem...

command for breaking link in excel is not seen.
i have copied files containing fromulas to another file. while opening the new file, each time, it is asking whetehr to update the data from parent file. I wish to break the link in second file, but could not find the command for that. while opening links, it shows only three commands, which odes not include command for ' breaking links'. Hi Suresh, If the links are no longer required, delete the link formulae or convert them to values. You may find Bill Manville's FINDLINK.XLA addin useful This is freely downloadable at: http://www.oaltd.co.uk/mvp --- Regards, ...

Can you link 2 worksheets together?
Say i have one worksheet and on my second one I want to reference cells from the first one? is there a formula for that>? To create a simple link: Select a cell in the second worksheet Type an equal sign Select the first sheet Click on the cell that you want to link Press the Enter key. Alesha wrote: > Say i have one worksheet and on my second one I want to reference cells from > the first one? is there a formula for that>? -- Debra Dalgleish Excel FAQ, Tips & Book List http://www.contextures.com/tiptech.html ...

modify linked cells without breaking link
I have a workbook with a number of worksheets (2003.) The 2nd and 3rd worksheets have cells that are linked to the 1st worksheet. This workbook will be used to schedule production. The 1st worksheet has a list of products that we produce. The 1st worksheet has a column for the min # of cases we need to keep in stock at all times and the max # of cases we must keep in stock at all times. The 1st worksheet also contains a column where the production scheduler would enter the actual # of cases in stock. The 2nd worksheet in the workbook takes the actual cs in stock and compares ...

Can I embed or link multiple .pdf files into or to an excel file?
I would like to link .pdf files to an excel file. Within my excel file I would like to have a column that has file names in it. Then have excel link those files to the excel file so when I print the excel file all the linked files print along with it. use hyper link "GrubbyG" wrote: > I would like to link .pdf files to an excel file. Within my excel file I > would like to have a column that has file names in it. Then have excel link > those files to the excel file so when I print the excel file all the linked > files print along with it. ...

Sending multiple Emails so each person does not get the list
We want to send out multiple emails to several email accounts. We dont want the accounts to see the list of accounts that the email went to. How does one do this in Outlook? In any contacts folder, Tools | Mail Merge is the best choice. --=20 Sue Mosher, Outlook MVP Author of Configuring Microsoft Outlook 2003 http://www.turtleflock.com/olconfig/index.htm and Microsoft Outlook Programming - Jumpstart for=20 Administrators, Power Users, and Developers http://www.outlookcode.com/jumpstart.aspx =20 "tom" <Spamblocker@ameritech.net> wrote in message = ...

User list
I'm wondering how to check the users on Exchange Server 2003, I tried it on E2k3 by [PS] W:\>Get-Mailbox -server Exchange2k3, and I got nothing in the list, but when I tried to remove Exchange Server 2003, I got an error, The component "Microsoft Exchange Messaging and Collaboration Services" cannot be assigned the action "Remove" because: - One or more users currently use a mailbox store on this server. These users must be moved to a mailbox store on a different server or be mail disabled before uninstalling this server. Any idea? Thanks. I followed the instruc...

How to remove locations from the drop-down list?
My drop down list for appointment locations contains a few duplicate entries, usually because one of the duplicates contains a spelling error. How can I get rid of these false entries so that I don't always have to be super-cautious to pick the correct one? M. "Michael Moser" <michael.nospam.moser@nospam.freesurf.ch> wrote in message news:DF17B5F2-DA57-48A7-B7DD-3B5A52F2A4E6@microsoft.com... > My drop down list for appointment locations contains a few duplicate > entries, usually because one of the duplicates contains a spelling error. > How ...

link file from virtual windows xp to access 2007 on windows 7 plat
I am trying to link a paradox db file to access 2007 db. The paradox file resides on a virtual windows xp platform within the windows 7 platform of the physical machine. How do I map this field into access? -- cblackman ...

Distribution list #7
How do I load a distribution list into the address book under a single heading ...

edit a drop down list
Hello, I have 2 questions 1. for an existing drop down list, how can I add a new entry? That is, a list named "division" now contains 5 items, and I want to add a sixth. I've tried to highlight all 6 items and typing "division" into the name box, but that just jumps me to the original 5 names. I also tried highlighting the original 5 and deleting the "division" from the name box, but again no luck. 2. Can I enlarge the font on a drop down list, so it appears larger when the arrow is clicked? The font is very small at present. To change the name r...

Customer Mailing List
Whats the best way to output the customer mailing list so that it doesn't require the entire content to be reformatted before printing out mailing labels? If exporting to a word .doc it lumps everything up in one column. Is there a better way w/out having to virtually reformat/retype all of the customers? Thanx in advance! Rich Export as a CSV, then use Mail Merge to load the fields. -- Jason Hunt Advanced Computer Systems You can use word mail merge to directly link to the database. No need to run a csv file. mt "Jason Hunt" <jhunt@advcs.ca> wrote in mess...

multiple pick from drop-down list
Does anyone know how to setup a drop-down type (or other type) list where I could pick multiple selections from the list and have it populate each selection in a different cell? Thanks, John Drop-downs do not lend themselves to multiple selections (what should be shown in the text area when the drop-down is not dropped down? You would probably be best off using a ListBox (it supports multiple selections). Can you give a more detailed description of what you want to do? Rick "johnrb7865" <johnrb7865@discussions.microsoft.com> wrote in message news:DD85C389-6AFC-4BC1-9...

Re: Uploaded version links & images not there
> Because the images (and other pages) are on your PC right where Publisher > put them but they are not on the web server because you failed to upload > them or uploaded them to the incorrect path. > I encourage you to review my upload tutorial at > www.davidbartosik.com/ppt.htm and suggest reviewing the FAQ page as well for > common issues like this. > If you need more "ideas", I recommend you use our web forum at > microsoft.public.publisher.webdesign in addition to my web site. > > -- > David Bartosik - Microsoft MVP > Visit www.davidbartosik.c...

Performance with SQL linked tables
Hi, My question is a application performance issue so maybe the wrong forum. I have a SQL Server 2005 Express database and connected Access 2003 clients. The performance seems to have degraded since moving from SQL 7. The users are seeing delays when clicking on menu optiosns that have open bound forms in Access. So I have been using the Profiler to have a look at things. I am filtering events SQL:Batchcompleted and RPC:Completed with duration > 10ms. I found some issues with the forms loading without filerting rows so i have changed it so it does not load any rows on opening. A...

Holiday listing
How do I get Publisher 2003 to automatically add major holidays to each month? ...

Recently used file list
Does anyone know if the size of the list can be increased from the default of 9? Thanks Tools/Options/General allows you to change the recently viewed size, but is pretty clear that the maximum is 9. >-----Original Message----- >Does anyone know if the size of the list can be increased >from the default of 9? > >Thanks >. > In xl2k and xl2002 (not sure about xl97), when you do a file|open, you'll see a History button in the left hand frame. Maybe you could use that to see more. Maria wrote: > > Does anyone know if the size of the list can be increased...

MS Exchange and Server 2003
Hey, At my company we run MS server 2003 and exchange 5.5. I want to send an email with an attachment to about 7500 users. we have IBM blade server with t1 connections. we have distribution list ready to go. What i want to know is that am i taking any chances in crashing the system. will this have any effect on the server. Thanks DJ ...

Dynamic Image references in a cell
I am exporting a report from Access 2007 to Excel 2007 containing product information. I have an image for each product. Access does not export Images to Word or Excel. I have the URL or local path for the image standardized so the path is C;/temp/image[ID Num].jpg or http://www.temp.com/images/image[ID num].jpg. I have [ID num] in Column B for each row. I want to reference the image column A of each row. How do I get the image to display in the cell? -- Jim Fidler ...

Subclassing dynamically created controls
I have a created an edit box dynamically using the Create function in a class derived from CTreeView ( Explorer Style - CLeftView ). Now I want to change the color of the edit box . I guess I need to subclass this window using SubClassWindow( ) . I have derived a class from CEdit and using the derived class to create the control . Can anyone please help me how to Subclass the edit control so I can change its background colour . Thanks in advance . Sujay -- Sujay Ghosh Bangalore, INDIA Sujay Ghosh wrote: > I have a created an edit box dynamically using the Create function in a ...

Updating links
Hi, In one of our office spreadsheets, everytime it is opened it asks do you want to update cells from another spreadsheet. I believe when this spreadsheet was set up, a work sheet was copied from another spreadsheet. I thought that all the references to that other spreadsheet had been removed. Is there anyway to identify (other than manually checking each cell) which cell has a formula linked to the old spreadsheet. Thanks in advance, George Download and install Bill Manville's FindLink add-in, which you can find at: http://www.bmsltd.ie/MVP/ In article <bYd1d.27315$Z14.90...