Identify error in how the pointers are handled [closed] - c++

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)

Related

Valgrind false memory leak for a pointer stored in a static std::list

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;
}

Do I need to deallocate object pointers in a vector?

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

How to correctly use and free asn1c SEQUENCE_OF?

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)

Invalid delete[] array of pointer

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.

Glib memory leak using valgrind investigation

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.