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.
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;
}
This question already has answers here:
PRE-2016 Valgrind: Memory still reachable with trivial program using <iostream>
(3 answers)
Closed 6 years ago.
Here is simplified version of the code, I deleted everything that doesn't concern the problem.
#include <iostream>
#define N 3
int main() {
int *input;
int **cl;
input = new int[N];
cl = new int*[N];
for(int i = 0; i < N; i++) {
cl[i] = new int[N];
}
for(int i = 0; i < N; i++) {
delete[] cl[i];
}
delete[] cl;
delete[] input;
return 0;
}
And the valgrind output:
==5782== HEAP SUMMARY:
==5782== in use at exit: 72,704 bytes in 1 blocks
==5782== total heap usage: 6 allocs, 5 frees, 72,776 bytes allocated
==5782==
==5782== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==5782== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5782== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==5782== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==5782== by 0x40105FA: call_init (dl-init.c:30)
==5782== by 0x40105FA: _dl_init (dl-init.c:120)
==5782== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==5782==
==5782== LEAK SUMMARY:
==5782== definitely lost: 0 bytes in 0 blocks
==5782== indirectly lost: 0 bytes in 0 blocks
==5782== possibly lost: 0 bytes in 0 blocks
==5782== still reachable: 72,704 bytes in 1 blocks
==5782== suppressed: 0 bytes in 0 blocks
==5782==
==5782== For counts of detected and suppressed errors, rerun with: -v
==5782== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I just started to learn C++, maybe there is some stupid error that I cannot see.
I know I should also check for example if there was no "out of memory" error when allocating, but I ignore it so that code is more clear. I also know I could use e.g. vector and don't care for the allocation, but I'm still concerned what I do wrong.
C++ provides you with tools, that encapsulate memory management for you.
#include <iostream>
#include <vector>
int main() {
// read the size for the vectors
int n;
std::cin >> n >> '\n';
// allocate vector with n elements
auto input = std::vector<int>{n};
// read the elements
for(int i = 0; i < n; i++) {
std::cin >> std::setw(1) >> input[i];
}
// print them
for(const auto& d : input) {
std::cout << d << std::endl;
}
// allocate the vectors and store 1 in each field.
auto Cl = std::vector<std::vector<int>>{n, std::vector<int>{n, 1}};
auto Cr = std::vector<std::vector<int>>{n, std::vector<int>{n, 1}};
return 0;
// will safely release all the memory here.
}
This looks a lot more like C++, and less like C. The vectors will handle all the memory management automatically for you.
Beware: I have not tested this code, so it will probably contain some bugs. I assume C++11 syntax, but it should be easy to change the code to older C++ syntax as well.
Now that you've added the valgrind output it's clearly the same issue as the one that has an answer here: Valgrind: Memory still reachable with trivial program using <iostream>
The short story is that it's not your code that causes that report. You can remove everything from main() and just return and valgrind will still give you that leak.
Read the accepted answer on that question for the explanation.
Minimal code example is as follows:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <regex.h>
using namespace std;
class regex_result {
public:
/** Contains indices of starting positions of matches.*/
std::vector<int> positions;
/** Contains lengths of matches.*/
std::vector<int> lengths;
};
regex_result match_regex(string regex_string, const char* string) {
regex_result result;
regex_t* regex = new regex_t;
regcomp(regex, regex_string.c_str(), REG_EXTENDED);
/* "P" is a pointer into the string which points to the end of the
previous match. */
const char* pointer = string;
/* "n_matches" is the maximum number of matches allowed. */
const int n_matches = 10;
regmatch_t matches[n_matches];
int nomatch = 0;
while (!nomatch) {
nomatch = regexec(regex, pointer, n_matches, matches, 0);
if (nomatch)
break;
for (int i = 0; i < n_matches; i++) {
int start,
finish;
if (matches[i].rm_so == -1) {
break;
}
start = matches[i].rm_so + (pointer - string);
finish = matches[i].rm_eo + (pointer - string);
result.positions.push_back(start);
result.lengths.push_back(finish - start);
}
pointer += matches[0].rm_eo;
}
delete regex;
return result;
}
int main(int argc, char** argv) {
string str = "this is a test";
string pat = "this";
regex_result res = match_regex(pat, str.c_str());
cout << res.positions.size() << endl;
return 0;
}
So I have written a function that parses a given string for regular expression matches. The result is held in a class that is essentially two vectors, one for the positions of the matches and one for the corresponding match lengths.
This works fine, but when I ran valgrind over it, it shows some substantial memory leaks.
When using valgrind --leak-check=full on the code above I get:
==24843== Memcheck, a memory error detector
==24843== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==24843== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==24843== Command: ./test
==24843==
1
==24843==
==24843== HEAP SUMMARY:
==24843== in use at exit: 11,688 bytes in 37 blocks
==24843== total heap usage: 54 allocs, 17 frees, 12,868 bytes allocated
==24843==
==24843== 256 bytes in 1 blocks are definitely lost in loss record 14 of 18
==24843== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24843== by 0x543549A: regcomp (regcomp.c:487)
==24843== by 0x400ED0: match_regex(std::string, char const*) (in <path>)
==24843== by 0x4010CA: main (in <path>)
==24843==
==24843== 11,432 (224 direct, 11,208 indirect) bytes in 1 blocks are definitely lost in loss record 18 of 18
==24843== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24843== by 0x4C2CF1F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24843== by 0x5434BAF: re_compile_internal (regcomp.c:760)
==24843== by 0x54354FF: regcomp (regcomp.c:506)
==24843== by 0x400ED0: match_regex(std::string, char const*) (in <path>)
==24843== by 0x4010CA: main (in <path>)
==24843==
==24843== LEAK SUMMARY:
==24843== definitely lost: 480 bytes in 2 blocks
==24843== indirectly lost: 11,208 bytes in 35 blocks
==24843== possibly lost: 0 bytes in 0 blocks
==24843== still reachable: 0 bytes in 0 blocks
==24843== suppressed: 0 bytes in 0 blocks
==24843==
==24843== For counts of detected and suppressed errors, rerun with: -v
==24843== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Is my code wrong or is there really a bug in those files?
Your regex_t management is not required to be dynamic, and though that isn't directly related to you problem, it is a little odd. The real problem is you never regfree() your resulting expression if compiled successfully (which you should verify). You should setup your regular expression like this:
regex_t regex;
int res = regcomp(®ex, regex_string.c_str(), REG_EXTENDED);
if (res == 0)
{
// use your expression via ®ex
....
// and eventually free it when done.
regfree(®ex);
}
If your implementation supports them, I strongly advise using the C++11 provided <regex> library, as it has nice RAII solutions to much of this.
You must call regfree() to free memory allocated by regcomp().
I know that there is similiar thread before here about this problem and on this site https://live.gnome.org/Valgrind had been explained, I wrote my simple program below
#include <glib.h>
#include <glib/gprintf.h>
#include <iostream>
int main()
{
const gchar *signalfound = g_strsignal(1);
std::cout << signalfound<< std::endl;
return 0;
}
but when I tried to check using valgrind using this command
G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=full --leak-resolution=high ./g_strsignal
and here is the result
==30274== Memcheck, a memory error detector
==30274== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==30274== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==30274== Command: ./g_strsignal
==30274== Parent PID: 5201
==30274==
==30274==
==30274== HEAP SUMMARY:
==30274== in use at exit: 14,746 bytes in 18 blocks
==30274== total heap usage: 24 allocs, 6 frees, 23,503 bytes allocated
==30274==
==30274== LEAK SUMMARY:
==30274== definitely lost: 0 bytes in 0 blocks
==30274== indirectly lost: 0 bytes in 0 blocks
==30274== possibly lost: 0 bytes in 0 blocks
==30274== still reachable: 14,746 bytes in 18 blocks
==30274== suppressed: 0 bytes in 0 blocks
==30274== Reachable blocks (those to which a pointer was found) are not shown.
==30274== To see them, rerun with: --leak-check=full --show-reachable=yes
==30274==
==30274== For counts of detected and suppressed errors, rerun with: -v
==30274== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I noticed that what was valgrind said "Reachable blocks (those to which a pointer was found) are not shown.". then I try to check the gmem.c
source on corresponding function since I used glib-2.35.4 version. I found following code
gpointer
g_malloc (gsize n_bytes)
{
if (G_LIKELY (n_bytes))
{
gpointer mem;
mem = glib_mem_vtable.malloc (n_bytes);
TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0));
if (mem)
return mem;
g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
G_STRLOC, n_bytes);
}
TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0));
return NULL;
}
And my question is
Is this still a normal situation on where valgrind had said "Reachable blocks (those to which a pointer was found) are not shown.", and I think this statement is refer to the g_malloc function above in which has returning mem a gpointer variable?
If not are there any alternatives to solve, "still reachable: 14,746 bytes in 18 blocks" on what valgrind had said above?
I'm running x86 fedora 18
thanks
It most likely refers to dynamically allocated memory returned by the function g_strsignal().
valgrind says "Reachable blocks....", because a valid pointer(signalfound) still points to the dynamically allocated memory.
If Valgrind finds that a pointer to pointing to dynamic memory is lost(overwritten) then it reports a "definite leak...", Since it can conclusively say that the dynamic block of memory can never be freed. In your case the pointer still points to the block valgrind does not assume it is lost but it assumes it is probably by design.
Right now, I want to increase the size of the array using a function.
#include <iostream>
using namespace std;
void IncreaseArraySize(int* addr){
int* temp = new int[20];
for(int i=0;i<10;i++){
temp[i] = addr[i];
}
for(int i=10;i<20;i++){
temp[i] = i;
}
int* dummy = addr;
addr = temp;
delete[] dummy;
}
int main(){
int* test = new int[10];
for(int i=0;i<10;i++){
test[i] = i;
}
IncreaseArraySize(test);
for(int i=0;i<20;i++){
cout<<"at index "<<i<<"we have"<<test[i]<<endl;
}
cout<<"ok!"<<endl;
delete[] test;
}
I ran the code with:
valgrind --leak-check=full ./test 2>debug.txt
and this is what I got for the output:
at index 0we have0
at index 1we have1
at index 2we have2
at index 3we have3
at index 4we have4
at index 5we have5
at index 6we have6
at index 7we have7
at index 8we have8
at index 9we have9
at index 10we have0
at index 11we have0
at index 12we have0
at index 13we have0
at index 14we have0
at index 15we have0
at index 16we have0
at index 17we have0
at index 18we have112
at index 19we have0
ok!
and this is what I got at the debug.txt:
==4285== Memcheck, a memory error detector
==4285== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4285== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==4285== Command: ./test
==4285==
==4285== Invalid read of size 4
==4285== at 0x400997: main (test.cpp:24)
==4285== Address 0x596f040 is 0 bytes inside a block of size 40 free'd
==4285== at 0x4C27C6E: operator delete[](void*) (vg_replace_malloc.c:409)
==4285== by 0x400931: IncreaseArraySize(int*) (test.cpp:14)
==4285== by 0x400980: main (test.cpp:22)
==4285==
==4285== Invalid free() / delete / delete[]
==4285== at 0x4C27C6E: operator delete[](void*) (vg_replace_malloc.c:409)
==4285== by 0x400A16: main (test.cpp:27)
==4285== Address 0x596f040 is 0 bytes inside a block of size 40 free'd
==4285== at 0x4C27C6E: operator delete[](void*) (vg_replace_malloc.c:409)
==4285== by 0x400931: IncreaseArraySize(int*) (test.cpp:14)
==4285== by 0x400980: main (test.cpp:22)
==4285==
==4285==
==4285== HEAP SUMMARY:
==4285== in use at exit: 80 bytes in 1 blocks
==4285== total heap usage: 2 allocs, 2 frees, 120 bytes allocated
==4285==
==4285== 80 bytes in 1 blocks are definitely lost in loss record 1 of 1
==4285== at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
==4285== by 0x4008A9: IncreaseArraySize(int*) (test.cpp:5)
==4285== by 0x400980: main (test.cpp:22)
==4285==
==4285== LEAK SUMMARY:
==4285== definitely lost: 80 bytes in 1 blocks
==4285== indirectly lost: 0 bytes in 0 blocks
==4285== possibly lost: 0 bytes in 0 blocks
==4285== still reachable: 0 bytes in 0 blocks
==4285== suppressed: 0 bytes in 0 blocks
==4285==
==4285== For counts of detected and suppressed errors, rerun with: -v
==4285== ERROR SUMMARY: 22 errors from 3 contexts (suppressed: 4 from 4)
Could you explain this in newbie terms?
I believe that your problem is that because you are passing the pointer to the start of the array by value, once you've updated and reassigned it, the changes aren't propagating to the caller. If you change the function so that it takes the pointer by reference, this should be fixed:
void IncreaseArraySize(int*& addr){
Right now, your bug is caused because when you call
IncreaseArraySize(test);
The test pointer back in main isn't getting reassigned. As a result, once you delete[] it in IncreaseArraySize, it references garbage memory. Updating the parameter so that it's passed by reference means that when, in IncreaseArraySize, you say
addr = temp;
This will update the test pointer in main, preventing the bug.
Hope this helps!
Well the most appropriate way to correct this code is to not use new at all, just use:
std:vector
Also, the problem with your code in particular is that you are passing the pointer addr by value, which creates a temporary and passes it to the function. Any changes made to this pointer inside the function are made on the copy of the pointer and not the original pointer.You need addr by reference, so that the changes inside the function are made on the pointer and get reflected outside the function.
void IncreaseArraySize(int*& addr)