Scope of heap memory allocated with new in c++
New learner for data structure, recently learning Listnode. Got questions.
Define a ListNode:
struct ListNode
{
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
void AddToTail(ListNode** head, int value)
{
ListNode* nlist = new ListNode(value);
if(*head == NULL)
{
*head = nlist;
}
else
{
ListNode* p = *head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
// No need to delete nlist, since the memory allocated by it is already organized by the ListNode.
}
int main()
{
ListNode* L = new ListNode(5);
AddToTail(&L, 10);
ListNode* p = L;
while(p->next != NULL)
{
p = p->next;
}
printf("Final value is %d.n", p->val);
delete L;
}
Till now, everything seems ok right? I wonder what if i don't allocate the ListNode memory in heap, that means i don't use new, while i use ListNode L;
then initialize it manually. The memeory of it is now in stack. The tail added to it is in heap memory. How do i delete the heap memory right now. It seems part of the ListNode memory is in stack and part of it is in heap? Am i correctly understood?
c++
|
show 2 more comments
New learner for data structure, recently learning Listnode. Got questions.
Define a ListNode:
struct ListNode
{
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
void AddToTail(ListNode** head, int value)
{
ListNode* nlist = new ListNode(value);
if(*head == NULL)
{
*head = nlist;
}
else
{
ListNode* p = *head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
// No need to delete nlist, since the memory allocated by it is already organized by the ListNode.
}
int main()
{
ListNode* L = new ListNode(5);
AddToTail(&L, 10);
ListNode* p = L;
while(p->next != NULL)
{
p = p->next;
}
printf("Final value is %d.n", p->val);
delete L;
}
Till now, everything seems ok right? I wonder what if i don't allocate the ListNode memory in heap, that means i don't use new, while i use ListNode L;
then initialize it manually. The memeory of it is now in stack. The tail added to it is in heap memory. How do i delete the heap memory right now. It seems part of the ListNode memory is in stack and part of it is in heap? Am i correctly understood?
c++
You're leaking memory regardless. Nothing is deleting the node created byAddToTail
.
– Rotem
Nov 15 '18 at 10:30
1
Don't mix memory allocated on the stack and in the heap in a container without tracking who is responsible for deleting the objects.
– Matthieu Brucher
Nov 15 '18 at 10:30
@Rotem Then how can i delete the tail added byAddToTail
?
– BigEd
Nov 15 '18 at 10:36
ALL dynamically allocated objects (e.g. created by anew
expression) must be explicitly released (e.g. with a correspondingdelete
expression) and no other objects should be explicitly released. That is true regardless of how you mix up objects "in stack" (incorrect description for an object of automatic storage duration) with "in heap" (incorrect description of pointer to dynamically allocated object). If you mix use of dynamic memory allocation and objects of automatic storage duration, you are responsible for ensuring only the dynamically allocated ones are released.
– Peter
Nov 15 '18 at 10:38
@BigEd Depends how you define responsibility in your data structure. Something must be in charge of callingdelete
onnew
ed objects. One scenario might be that each node deletes the subsequent node before deleting itself, triggering a recursive deletion. Another scenario is that you delegate that responsibility to the user of the data structure, and if you do, it might make more sense to also delegate the responsibility of allocating theListNode
to the user as well.
– Rotem
Nov 15 '18 at 10:48
|
show 2 more comments
New learner for data structure, recently learning Listnode. Got questions.
Define a ListNode:
struct ListNode
{
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
void AddToTail(ListNode** head, int value)
{
ListNode* nlist = new ListNode(value);
if(*head == NULL)
{
*head = nlist;
}
else
{
ListNode* p = *head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
// No need to delete nlist, since the memory allocated by it is already organized by the ListNode.
}
int main()
{
ListNode* L = new ListNode(5);
AddToTail(&L, 10);
ListNode* p = L;
while(p->next != NULL)
{
p = p->next;
}
printf("Final value is %d.n", p->val);
delete L;
}
Till now, everything seems ok right? I wonder what if i don't allocate the ListNode memory in heap, that means i don't use new, while i use ListNode L;
then initialize it manually. The memeory of it is now in stack. The tail added to it is in heap memory. How do i delete the heap memory right now. It seems part of the ListNode memory is in stack and part of it is in heap? Am i correctly understood?
c++
New learner for data structure, recently learning Listnode. Got questions.
Define a ListNode:
struct ListNode
{
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
void AddToTail(ListNode** head, int value)
{
ListNode* nlist = new ListNode(value);
if(*head == NULL)
{
*head = nlist;
}
else
{
ListNode* p = *head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
// No need to delete nlist, since the memory allocated by it is already organized by the ListNode.
}
int main()
{
ListNode* L = new ListNode(5);
AddToTail(&L, 10);
ListNode* p = L;
while(p->next != NULL)
{
p = p->next;
}
printf("Final value is %d.n", p->val);
delete L;
}
Till now, everything seems ok right? I wonder what if i don't allocate the ListNode memory in heap, that means i don't use new, while i use ListNode L;
then initialize it manually. The memeory of it is now in stack. The tail added to it is in heap memory. How do i delete the heap memory right now. It seems part of the ListNode memory is in stack and part of it is in heap? Am i correctly understood?
c++
c++
asked Nov 15 '18 at 10:24
BigEdBigEd
212
212
You're leaking memory regardless. Nothing is deleting the node created byAddToTail
.
– Rotem
Nov 15 '18 at 10:30
1
Don't mix memory allocated on the stack and in the heap in a container without tracking who is responsible for deleting the objects.
– Matthieu Brucher
Nov 15 '18 at 10:30
@Rotem Then how can i delete the tail added byAddToTail
?
– BigEd
Nov 15 '18 at 10:36
ALL dynamically allocated objects (e.g. created by anew
expression) must be explicitly released (e.g. with a correspondingdelete
expression) and no other objects should be explicitly released. That is true regardless of how you mix up objects "in stack" (incorrect description for an object of automatic storage duration) with "in heap" (incorrect description of pointer to dynamically allocated object). If you mix use of dynamic memory allocation and objects of automatic storage duration, you are responsible for ensuring only the dynamically allocated ones are released.
– Peter
Nov 15 '18 at 10:38
@BigEd Depends how you define responsibility in your data structure. Something must be in charge of callingdelete
onnew
ed objects. One scenario might be that each node deletes the subsequent node before deleting itself, triggering a recursive deletion. Another scenario is that you delegate that responsibility to the user of the data structure, and if you do, it might make more sense to also delegate the responsibility of allocating theListNode
to the user as well.
– Rotem
Nov 15 '18 at 10:48
|
show 2 more comments
You're leaking memory regardless. Nothing is deleting the node created byAddToTail
.
– Rotem
Nov 15 '18 at 10:30
1
Don't mix memory allocated on the stack and in the heap in a container without tracking who is responsible for deleting the objects.
– Matthieu Brucher
Nov 15 '18 at 10:30
@Rotem Then how can i delete the tail added byAddToTail
?
– BigEd
Nov 15 '18 at 10:36
ALL dynamically allocated objects (e.g. created by anew
expression) must be explicitly released (e.g. with a correspondingdelete
expression) and no other objects should be explicitly released. That is true regardless of how you mix up objects "in stack" (incorrect description for an object of automatic storage duration) with "in heap" (incorrect description of pointer to dynamically allocated object). If you mix use of dynamic memory allocation and objects of automatic storage duration, you are responsible for ensuring only the dynamically allocated ones are released.
– Peter
Nov 15 '18 at 10:38
@BigEd Depends how you define responsibility in your data structure. Something must be in charge of callingdelete
onnew
ed objects. One scenario might be that each node deletes the subsequent node before deleting itself, triggering a recursive deletion. Another scenario is that you delegate that responsibility to the user of the data structure, and if you do, it might make more sense to also delegate the responsibility of allocating theListNode
to the user as well.
– Rotem
Nov 15 '18 at 10:48
You're leaking memory regardless. Nothing is deleting the node created by
AddToTail
.– Rotem
Nov 15 '18 at 10:30
You're leaking memory regardless. Nothing is deleting the node created by
AddToTail
.– Rotem
Nov 15 '18 at 10:30
1
1
Don't mix memory allocated on the stack and in the heap in a container without tracking who is responsible for deleting the objects.
– Matthieu Brucher
Nov 15 '18 at 10:30
Don't mix memory allocated on the stack and in the heap in a container without tracking who is responsible for deleting the objects.
– Matthieu Brucher
Nov 15 '18 at 10:30
@Rotem Then how can i delete the tail added by
AddToTail
?– BigEd
Nov 15 '18 at 10:36
@Rotem Then how can i delete the tail added by
AddToTail
?– BigEd
Nov 15 '18 at 10:36
ALL dynamically allocated objects (e.g. created by a
new
expression) must be explicitly released (e.g. with a corresponding delete
expression) and no other objects should be explicitly released. That is true regardless of how you mix up objects "in stack" (incorrect description for an object of automatic storage duration) with "in heap" (incorrect description of pointer to dynamically allocated object). If you mix use of dynamic memory allocation and objects of automatic storage duration, you are responsible for ensuring only the dynamically allocated ones are released.– Peter
Nov 15 '18 at 10:38
ALL dynamically allocated objects (e.g. created by a
new
expression) must be explicitly released (e.g. with a corresponding delete
expression) and no other objects should be explicitly released. That is true regardless of how you mix up objects "in stack" (incorrect description for an object of automatic storage duration) with "in heap" (incorrect description of pointer to dynamically allocated object). If you mix use of dynamic memory allocation and objects of automatic storage duration, you are responsible for ensuring only the dynamically allocated ones are released.– Peter
Nov 15 '18 at 10:38
@BigEd Depends how you define responsibility in your data structure. Something must be in charge of calling
delete
on new
ed objects. One scenario might be that each node deletes the subsequent node before deleting itself, triggering a recursive deletion. Another scenario is that you delegate that responsibility to the user of the data structure, and if you do, it might make more sense to also delegate the responsibility of allocating the ListNode
to the user as well.– Rotem
Nov 15 '18 at 10:48
@BigEd Depends how you define responsibility in your data structure. Something must be in charge of calling
delete
on new
ed objects. One scenario might be that each node deletes the subsequent node before deleting itself, triggering a recursive deletion. Another scenario is that you delegate that responsibility to the user of the data structure, and if you do, it might make more sense to also delegate the responsibility of allocating the ListNode
to the user as well.– Rotem
Nov 15 '18 at 10:48
|
show 2 more comments
2 Answers
2
active
oldest
votes
Yeah, it doesn't really matter whether L
is dynamically allocated or not. That's by-the-by. In fact there's no reason here to dynamically allocate it.
What matters is the ownership and lifetime of the nodes that it manages. These are dynamically allocated, so you will need a destructor inside ListNode
that unlinks and de-allocates the nodes.
There's nothing wrong with "mixing" storage duration — that's what you're doing every time you instantiate a std::vector<int>
, for example. You just need to ensure that anything owning dynamically allocated data has the capability to clean up after itself.
add a comment |
You need some delete function like this
void DeleteList(ListNode** head)
{
ListNode* p = *head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
}
// and call it in main:
printf("Final value is %d.n", p->val);
DeleteList(&L);
But it is better to immediately define all these operations in a special class, such as List:
class List
{
private:
ListNode *head;
public:
List() : head(NULL){}
~List() { Clear(); }
void AddToTail(int value);
void Clear();
};
void List::AddToTail(int value)
{
ListNode* nlist = new ListNode(value);
if(head == NULL)
{
head = nlist;
}
else
{
ListNode* p = head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
}
void List::Clear()
{
ListNode* p = head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
head = NULL;
}
and use it like this:
List lst;
lst.AddToTail(5);
lst.AddToTail(10);
lst.AddToTail(20);
lst.AddToTail(30);
lst.Clear();
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317266%2fscope-of-heap-memory-allocated-with-new-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Yeah, it doesn't really matter whether L
is dynamically allocated or not. That's by-the-by. In fact there's no reason here to dynamically allocate it.
What matters is the ownership and lifetime of the nodes that it manages. These are dynamically allocated, so you will need a destructor inside ListNode
that unlinks and de-allocates the nodes.
There's nothing wrong with "mixing" storage duration — that's what you're doing every time you instantiate a std::vector<int>
, for example. You just need to ensure that anything owning dynamically allocated data has the capability to clean up after itself.
add a comment |
Yeah, it doesn't really matter whether L
is dynamically allocated or not. That's by-the-by. In fact there's no reason here to dynamically allocate it.
What matters is the ownership and lifetime of the nodes that it manages. These are dynamically allocated, so you will need a destructor inside ListNode
that unlinks and de-allocates the nodes.
There's nothing wrong with "mixing" storage duration — that's what you're doing every time you instantiate a std::vector<int>
, for example. You just need to ensure that anything owning dynamically allocated data has the capability to clean up after itself.
add a comment |
Yeah, it doesn't really matter whether L
is dynamically allocated or not. That's by-the-by. In fact there's no reason here to dynamically allocate it.
What matters is the ownership and lifetime of the nodes that it manages. These are dynamically allocated, so you will need a destructor inside ListNode
that unlinks and de-allocates the nodes.
There's nothing wrong with "mixing" storage duration — that's what you're doing every time you instantiate a std::vector<int>
, for example. You just need to ensure that anything owning dynamically allocated data has the capability to clean up after itself.
Yeah, it doesn't really matter whether L
is dynamically allocated or not. That's by-the-by. In fact there's no reason here to dynamically allocate it.
What matters is the ownership and lifetime of the nodes that it manages. These are dynamically allocated, so you will need a destructor inside ListNode
that unlinks and de-allocates the nodes.
There's nothing wrong with "mixing" storage duration — that's what you're doing every time you instantiate a std::vector<int>
, for example. You just need to ensure that anything owning dynamically allocated data has the capability to clean up after itself.
answered Nov 15 '18 at 11:25
Lightness Races in OrbitLightness Races in Orbit
292k53475807
292k53475807
add a comment |
add a comment |
You need some delete function like this
void DeleteList(ListNode** head)
{
ListNode* p = *head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
}
// and call it in main:
printf("Final value is %d.n", p->val);
DeleteList(&L);
But it is better to immediately define all these operations in a special class, such as List:
class List
{
private:
ListNode *head;
public:
List() : head(NULL){}
~List() { Clear(); }
void AddToTail(int value);
void Clear();
};
void List::AddToTail(int value)
{
ListNode* nlist = new ListNode(value);
if(head == NULL)
{
head = nlist;
}
else
{
ListNode* p = head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
}
void List::Clear()
{
ListNode* p = head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
head = NULL;
}
and use it like this:
List lst;
lst.AddToTail(5);
lst.AddToTail(10);
lst.AddToTail(20);
lst.AddToTail(30);
lst.Clear();
add a comment |
You need some delete function like this
void DeleteList(ListNode** head)
{
ListNode* p = *head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
}
// and call it in main:
printf("Final value is %d.n", p->val);
DeleteList(&L);
But it is better to immediately define all these operations in a special class, such as List:
class List
{
private:
ListNode *head;
public:
List() : head(NULL){}
~List() { Clear(); }
void AddToTail(int value);
void Clear();
};
void List::AddToTail(int value)
{
ListNode* nlist = new ListNode(value);
if(head == NULL)
{
head = nlist;
}
else
{
ListNode* p = head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
}
void List::Clear()
{
ListNode* p = head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
head = NULL;
}
and use it like this:
List lst;
lst.AddToTail(5);
lst.AddToTail(10);
lst.AddToTail(20);
lst.AddToTail(30);
lst.Clear();
add a comment |
You need some delete function like this
void DeleteList(ListNode** head)
{
ListNode* p = *head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
}
// and call it in main:
printf("Final value is %d.n", p->val);
DeleteList(&L);
But it is better to immediately define all these operations in a special class, such as List:
class List
{
private:
ListNode *head;
public:
List() : head(NULL){}
~List() { Clear(); }
void AddToTail(int value);
void Clear();
};
void List::AddToTail(int value)
{
ListNode* nlist = new ListNode(value);
if(head == NULL)
{
head = nlist;
}
else
{
ListNode* p = head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
}
void List::Clear()
{
ListNode* p = head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
head = NULL;
}
and use it like this:
List lst;
lst.AddToTail(5);
lst.AddToTail(10);
lst.AddToTail(20);
lst.AddToTail(30);
lst.Clear();
You need some delete function like this
void DeleteList(ListNode** head)
{
ListNode* p = *head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
}
// and call it in main:
printf("Final value is %d.n", p->val);
DeleteList(&L);
But it is better to immediately define all these operations in a special class, such as List:
class List
{
private:
ListNode *head;
public:
List() : head(NULL){}
~List() { Clear(); }
void AddToTail(int value);
void Clear();
};
void List::AddToTail(int value)
{
ListNode* nlist = new ListNode(value);
if(head == NULL)
{
head = nlist;
}
else
{
ListNode* p = head;
while(p->next != NULL)
{
p = p->next;
}
p->next = nlist;
}
}
void List::Clear()
{
ListNode* p = head;
while(p != NULL)
{
ListNode *t = p->next;
delete p;
p = t;
}
head = NULL;
}
and use it like this:
List lst;
lst.AddToTail(5);
lst.AddToTail(10);
lst.AddToTail(20);
lst.AddToTail(30);
lst.Clear();
edited Nov 15 '18 at 11:32
answered Nov 15 '18 at 11:19
snake_stylesnake_style
1,170410
1,170410
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317266%2fscope-of-heap-memory-allocated-with-new-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You're leaking memory regardless. Nothing is deleting the node created by
AddToTail
.– Rotem
Nov 15 '18 at 10:30
1
Don't mix memory allocated on the stack and in the heap in a container without tracking who is responsible for deleting the objects.
– Matthieu Brucher
Nov 15 '18 at 10:30
@Rotem Then how can i delete the tail added by
AddToTail
?– BigEd
Nov 15 '18 at 10:36
ALL dynamically allocated objects (e.g. created by a
new
expression) must be explicitly released (e.g. with a correspondingdelete
expression) and no other objects should be explicitly released. That is true regardless of how you mix up objects "in stack" (incorrect description for an object of automatic storage duration) with "in heap" (incorrect description of pointer to dynamically allocated object). If you mix use of dynamic memory allocation and objects of automatic storage duration, you are responsible for ensuring only the dynamically allocated ones are released.– Peter
Nov 15 '18 at 10:38
@BigEd Depends how you define responsibility in your data structure. Something must be in charge of calling
delete
onnew
ed objects. One scenario might be that each node deletes the subsequent node before deleting itself, triggering a recursive deletion. Another scenario is that you delegate that responsibility to the user of the data structure, and if you do, it might make more sense to also delegate the responsibility of allocating theListNode
to the user as well.– Rotem
Nov 15 '18 at 10:48