I'm confused as to how deallocating vector memory works.
For the example below,
vector<Object*> vec;
for(int i = 0; i < 10; i++){
Object* obj = new Object();
vec.push_pack(obj);
}
//DEALLOCATE CODE HERE//
What should I do to deallocate vec properly?
The program seems to run fine as it is but I'm not sure.
avoid using new/delete :
std::vector<std::unique_ptr<Object>> vec;
for(int i = 0; i < 10; i++)
{
vec.push_pack(std::make_unique<Object>());
}
the unique_ptr will take care of deletion
how deallocating
for instance do
for(auto o : vect){
delete o;
}
vect.clear();
Note you written push_pack rather than push_back to fill the vector
making a full program :
#include <vector>
using namespace std;
class Object{};
int main()
{
vector<Object*> vec;
for(int i = 0; i < 10; i++){
Object* obj = new Object();
vec.push_back(obj);
}
for(auto o : vec){
delete o;
}
vec.clear();
}
Compilation and execution under valgrind :
pi#raspberrypi:/tmp $ g++ v.cc
pi#raspberrypi:/tmp $ valgrind ./a.out
==9157== Memcheck, a memory error detector
==9157== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9157== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9157== Command: ./a.out
==9157==
==9157==
==9157== HEAP SUMMARY:
==9157== in use at exit: 0 bytes in 0 blocks
==9157== total heap usage: 16 allocs, 16 frees, 20,358 bytes allocated
==9157==
==9157== All heap blocks were freed -- no leaks are possible
==9157==
==9157== For counts of detected and suppressed errors, rerun with: -v
==9157== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
all allocated memory was freed
Related
Valgrind shows a memory leak for a pointer stored in static std::list variable. below is the sample code.
Leak shown for "auto t = new Abc;" ( definitely lost: 4 bytes in 1 blocks)
Is this a BUG in Valgrind ?
Is there a solution/workaround (other than clearing the Pool::queue manually) ?
#include <list>
struct Abc
{
int y = 9;
};
struct Pool
{
static std::list<Abc*> queue;
~Pool()
{
for (auto p : queue)
{
delete p;
}
}
};
std::list<Abc*> Pool::queue;
int main ()
{
auto t = new Abc; //<<<<<<<<<<< Leak shown for this
Pool::queue.push_back(t);
return 0;
}
Valgrind output
g++ -ggdb Main.cpp
valgrind --leak-check=full ./a.out
==8807== Memcheck, a memory error detector
==8807== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8807== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8807== Command: ./a.out
==8807==
==8807==
==8807== HEAP SUMMARY:
==8807== in use at exit: 4 bytes in 1 blocks
==8807== total heap usage: 3 allocs, 2 frees, 72,732 bytes allocated
==8807==
==8807== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8807== at 0x4C2A1E3: operator new(unsigned long) (vg_replace_malloc.c:334)
==8807== by 0x4007D9: main (Main.cpp:26)
==8807==
==8807== LEAK SUMMARY:
==8807== definitely lost: 4 bytes in 1 blocks
==8807== indirectly lost: 0 bytes in 0 blocks
==8807== possibly lost: 0 bytes in 0 blocks
==8807== still reachable: 0 bytes in 0 blocks
==8807== suppressed: 0 bytes in 0 blocks
==8807==
==8807== For counts of detected and suppressed errors, rerun with: -v
==8807== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
The std::list destructs (the compiler takes care of that for a static object), the objects in it don't as that's the job of ~Pool, which the code doesn't invoke anywhere. The Abc instance survives and is indeed not reachable, the leak report is correct.
Answer by #dratenik is the correct answer, I am posting the modified code according to his answer so that some other dev my might find it useful
#include <list>
struct Abc
{
int y = 9;
};
struct List
{
std::list<Abc*> queue;
void push_back(Abc* p)
{
queue.push_back(p);
}
~List()
{
for (auto& p : queue)
{
delete p;
}
}
};
struct Pool
{
static List queue;
};
List Pool::queue;
int main ()
{
auto t = new Abc;
Pool::queue.push_back(t);
return 0;
}
I am trying to submit my solution on leetcode, when I submit it it gives me a run time error.
AddressSanitizer: stack-buffer-overflow on address 0x7ffd6484f411 at pc 0x000000386795 bp 0x7ffd6484ed70 sp 0x7ffd6484ed68
Here is my code:
int lengthOfLongestSubstring(std::string s)
{
auto start = std::begin(s);
std::string substring = std::string(std::begin(s), std::begin(s) + 1);
std::string pre_string = std::string(std::begin(s), std::begin(s) + 1);
for (auto itr = std::begin(s) + 1; itr != std::end(s); ++itr)
{
auto next = itr;
if (std::find(std::begin(substring), std::end(substring), *itr) ==
std::end(substring))
{
substring = std::string(start, itr + 1);
}
else
{
if (++next != std::end(s))
{
start = itr;
pre_string = substring;
substring = std::string(itr, ++itr);
}
}
}
if (pre_string.length() > substring.length())
{
return pre_string.length();
}
else
return substring.length();
}
when I try to run it on my machine, It does not give me any warning. It's running totally fine.
I am using the following command.
g++ -Wall -Wpedantic longestString.cpp -o long.o
and further I used valgrind to see the any problem but it also says there is no problem as you can see the output.
username#droozal:~/leetcode$ valgrind ./long.o
==9473== Memcheck, a memory error detector
==9473== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9473== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9473== Command: ./long.o
==9473==
5
==9473==
==9473== HEAP SUMMARY:
==9473== in use at exit: 0 bytes in 0 blocks
==9473== total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==9473==
==9473== All heap blocks were freed -- no leaks are possible
==9473==
==9473== For counts of detected and suppressed errors, rerun with: -v
==9473== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
so my question is what can be the potential error? is something broken in my code Or what? Answers will be appreciated. Thanks.
I see that you're trying to solve with constant memory, I guess. You can use memoization though for this problem, much simpler to code/debug.
This'll pass through:
#include <string>
#include <map>
#include <algorithm>
class Solution {
public:
static inline int lengthOfLongestSubstring(const std::string s) {
map<char, int> char_map;
int start = -1;
int longest = 0;
const int length = s.size();
for (int index = 0; index < length; index++) {
if (char_map.count(s[index]) != 0) {
start = std::max(start, char_map[s[index]]);
}
char_map[s[index]] = index;
longest = std::max(longest, index - start);
}
return longest;
}
};
References
For additional details, you can see the Discussion Board. There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time/space complexity analysis1, 2 in there.
I'm using the asn1c lib for many projects, but I never found how to use the free member of a SEQUENCE_OF. I always set it to nullptr because of that, and when I use Valgrind, I see (of course) that my lists members are not freed when using ASN_STRUCT_FREE on the element containing the list.
So my question is how can I use that free member?
Here is a simple example of how I use my lists with asn1c.
ListItem_t *li = nullptr;
StructWList_t swl;
swl.list.count = 0;
swl.list.size = 0;
swl.list.free = nullptr; // How can I feed it properly?
swl.list.array = reinterpret_cast<ListItem_t**>(calloc(1, sizeof *swl.list.array));
for(int i = 0 ; i < 5 ; i++)
{
li = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *li));
*li = i;
// Valgrind says that the calloc below is definitly lost
swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
ASN_SEQUENCE_ADD(&swl, li);
}
...
ASN_STRUCT_FREE(ASN_DEF_StructWList, &swl);
Does anyone know how to feed it properly?
EDIT
My version of asn1c is the v0.9.29 from git repository in AUR (on Archlinux).
The above ASN.1 is as follow:
Example
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
StructWList ::= SEQUENCE OF ListItem
ListItem ::= INTEGER
END
Thanks in advance,
Emilien
// Valgrind says that the calloc below is definitly lost
swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
ASN_SEQUENCE_ADD(&swl, li);
The ASN_SEQUENCE_ADD will overwrite the pointer you stored on the previous line. You should either store it manually as on the first line or call ASN_SEQUENCE_ADD but not both.
Also you should fully initialize swl as it contains more members (_asn_ctx) and use ASN_STRUCT_FREE_CONTENTS_ONLY as swl is allocated on the stack and cannot be freed.
--- main.cpp.orig 2019-05-07 20:49:25.880336931 +0300
+++ main.cpp 2019-05-07 20:59:10.192431926 +0300
## -3,7 +3,7 ##
int main()
{
ListItem_t *li = nullptr;
- StructWList_t swl;
+ StructWList_t swl = {0};
swl.list.count = 0;
swl.list.size = 0;
## -15,8 +15,8 ##
li = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *li));
*li = i;
// Valgrind says that the calloc below is definitly lost
- swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
+ //swl.list.array[i] = reinterpret_cast<ListItem_t*>(calloc(1, sizeof *swl.list.array[i]));
ASN_SEQUENCE_ADD(&swl, li);
}
- ASN_STRUCT_FREE(ASN_DEF_StructWList, &swl);
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_StructWList, &swl);
}
Compile with g++ -Wall -I. -ggdb -O0 -o test main.cpp libasncodec.a
valgrind --tool=memcheck ./test
==29555== Memcheck, a memory error detector
==29555== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==29555== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==29555== Command: ./test
==29555==
==29555==
==29555== HEAP SUMMARY:
==29555== in use at exit: 0 bytes in 0 blocks
==29555== total heap usage: 9 allocs, 9 frees, 72,848 bytes allocated
==29555==
==29555== All heap blocks were freed -- no leaks are possible
==29555==
==29555== For counts of detected and suppressed errors, rerun with: -v
==29555== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
The question want me to identify the error in how the pointers are handled.
I tried compiling it but it doesn't give any error.
#include <iostream>
using namespace std;
int main()
{
int *ptr = new int;
int *ptr2 = ptr;
delete ptr;
ptr = NULL;
return 0;
}
i guess you miss "int main()" line
#include <iostream>
using namespace std;
int main()
{
int *ptr = new int;
int *ptr2 = ptr;
delete ptr;
ptr = NULL;
return 0;
}
If you put your code in a main method and compile it valgrid is not giving you any error. What are you looking for?
valgrind --leak-check=full ./a.out
==22277== Memcheck, a memory error detector
==22277== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==22277== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==22277== Command: ./a.out
==22277==
==22277==
==22277== HEAP SUMMARY:
==22277== in use at exit: 0 bytes in 0 blocks
==22277== total heap usage: 1 allocs, 1 frees, 4 bytes allocated
==22277==
==22277== All heap blocks were freed -- no leaks are possible
==22277==
==22277== For counts of detected and suppressed errors, rerun with: -v
==22277== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 6)
I am learning to create array of pointer and free up memory. This is my simple code
#include <iostream>
using namespace std;
int main()
{
int* classroom[5];
for (int i = 0; i < 5; i++) {
classroom[i] = new int;
}
for (int i = 0; i < 5; i++) {
classroom[i] = &i;
cout<<*classroom[i]<<endl;
}
for (int i = 0; i < 5; i++) {
delete classroom[i];
}
return 0;
}
When I run in valgrind to check for the memory leak, this is the result
==2868== Memcheck, a memory error detector
==2868== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==2868== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==2868== Command: ./m
==2868==
0
1
2
3
4
==2868== Invalid free() / delete / delete[] / realloc()
==2868== at 0x402ACFC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2868== by 0x8048700: main (in /home/student/Downloads/demo/m)
==2868== Address 0xbea69244 is on thread 1's stack
==2868==
==2868==
==2868== HEAP SUMMARY:
==2868== in use at exit: 20 bytes in 5 blocks
==2868== total heap usage: 5 allocs, 5 frees, 20 bytes allocated
==2868==
==2868== LEAK SUMMARY:
==2868== definitely lost: 20 bytes in 5 blocks
==2868== indirectly lost: 0 bytes in 0 blocks
==2868== possibly lost: 0 bytes in 0 blocks
==2868== still reachable: 0 bytes in 0 blocks
==2868== suppressed: 0 bytes in 0 blocks
==2868== Rerun with --leak-check=full to see details of leaked memory
==2868==
==2868== For counts of detected and suppressed errors, rerun with: -v
==2868== ERROR SUMMARY: 5 errors from 1 contexts (suppressed: 0 from 0)
My question is, why I have received the message "invalid free()/delete/delete[]/realloc[]" ? and how to fix it ?
Thanks,
classroom[i] = &i;
should be:
*classroom[i] = i;
You're replacing the pointer that you allocated with new with the address of the local variable i. Then you later try to delete that pointer, but you can't delete local variables, only variables allocated with new. What you actually want to do is copy the value of i into the dynamically allocated variable.
I think the problem is that by the time you delete each classroom it no longer points to the original memory location of the int created by new because you are not pushing the value of i into the memory location of classroom[i], you are actually changing classroom[i] to point to i's memory location.
Try changing
classroom[i] = &i;
to
*(classroom[i]) = i;
In this loop
for (int i = 0; i < 5; i++) {
classroom[i] = &i;
cout<<*classroom[i]<<endl;
}
You are trashing the memory of the array. You set all of the pointers to the address of i and then when the for loop ends i is destroyed and you now have dangling pointers. attempting to delete them is undefined behavior.