Where does this memory leak come from?
In my implementation of ArrayList I have a method for resizing the array. It looks like this:
template<typename T>
int ArrayList<T>::changeSize(int newsize)
{
T* tmp = (T*)(T*)realloc(internal_array,sizeof(T)*newsize);
if(tmp == NULL)
{
return 0;
}
internal_array=tmp;
Capacity = newsize;
return 1;
}
This part of code causes a memory leak when using it, any idea, what could be wrong here?
EDIT: Handling realloc being NULL still didn't help, updated the code and added adress sanitizer output:
=================================================================
==4615==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b693e0b in ArrayList<int>::Remove(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2e0b)
#3 0x557b3b692d07 in findMinDistances(ArrayList<int>) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1d07)
#4 0x557b3b6934a3 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x24a3)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: 20 byte(s) leaked in 2 allocation(s).
c++ memory memory-leaks dynamic-memory-allocation realloc
|
show 2 more comments
In my implementation of ArrayList I have a method for resizing the array. It looks like this:
template<typename T>
int ArrayList<T>::changeSize(int newsize)
{
T* tmp = (T*)(T*)realloc(internal_array,sizeof(T)*newsize);
if(tmp == NULL)
{
return 0;
}
internal_array=tmp;
Capacity = newsize;
return 1;
}
This part of code causes a memory leak when using it, any idea, what could be wrong here?
EDIT: Handling realloc being NULL still didn't help, updated the code and added adress sanitizer output:
=================================================================
==4615==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b693e0b in ArrayList<int>::Remove(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2e0b)
#3 0x557b3b692d07 in findMinDistances(ArrayList<int>) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1d07)
#4 0x557b3b6934a3 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x24a3)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: 20 byte(s) leaked in 2 allocation(s).
c++ memory memory-leaks dynamic-memory-allocation realloc
1
How do you determine that it leaks? What do you do ifrealloc()
fails? Curious: what isT
?
– Swordfish
Nov 21 '18 at 2:08
3
The correct way to call realloc is to save the return value in a temporary variable and check it for NULL. That way if realloc has failed, you haven't lost your original memory, like in this answer: stackoverflow.com/a/44789446/1212725
– bruceg
Nov 21 '18 at 2:21
@Swordfish, it's a generic type, but in my program it's an integer (int
)
– Michal Dvořák
Nov 21 '18 at 11:03
Updated my question, checking the realloc isNULL
didn't help.
– Michal Dvořák
Nov 21 '18 at 11:20
Are you sure thatinternal_array
holds eitherNULL
or a valid pointer value returned bymalloc()
,calloc()
,realloc(NULL, ...)
before you callrealloc()
with it as the firest parameter?
– Swordfish
Nov 21 '18 at 13:42
|
show 2 more comments
In my implementation of ArrayList I have a method for resizing the array. It looks like this:
template<typename T>
int ArrayList<T>::changeSize(int newsize)
{
T* tmp = (T*)(T*)realloc(internal_array,sizeof(T)*newsize);
if(tmp == NULL)
{
return 0;
}
internal_array=tmp;
Capacity = newsize;
return 1;
}
This part of code causes a memory leak when using it, any idea, what could be wrong here?
EDIT: Handling realloc being NULL still didn't help, updated the code and added adress sanitizer output:
=================================================================
==4615==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b693e0b in ArrayList<int>::Remove(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2e0b)
#3 0x557b3b692d07 in findMinDistances(ArrayList<int>) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1d07)
#4 0x557b3b6934a3 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x24a3)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: 20 byte(s) leaked in 2 allocation(s).
c++ memory memory-leaks dynamic-memory-allocation realloc
In my implementation of ArrayList I have a method for resizing the array. It looks like this:
template<typename T>
int ArrayList<T>::changeSize(int newsize)
{
T* tmp = (T*)(T*)realloc(internal_array,sizeof(T)*newsize);
if(tmp == NULL)
{
return 0;
}
internal_array=tmp;
Capacity = newsize;
return 1;
}
This part of code causes a memory leak when using it, any idea, what could be wrong here?
EDIT: Handling realloc being NULL still didn't help, updated the code and added adress sanitizer output:
=================================================================
==4615==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b693e0b in ArrayList<int>::Remove(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2e0b)
#3 0x557b3b692d07 in findMinDistances(ArrayList<int>) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1d07)
#4 0x557b3b6934a3 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x24a3)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
SUMMARY: AddressSanitizer: 20 byte(s) leaked in 2 allocation(s).
c++ memory memory-leaks dynamic-memory-allocation realloc
c++ memory memory-leaks dynamic-memory-allocation realloc
edited Nov 21 '18 at 13:49
Swordfish
9,22211335
9,22211335
asked Nov 21 '18 at 2:02
Michal DvořákMichal Dvořák
1127
1127
1
How do you determine that it leaks? What do you do ifrealloc()
fails? Curious: what isT
?
– Swordfish
Nov 21 '18 at 2:08
3
The correct way to call realloc is to save the return value in a temporary variable and check it for NULL. That way if realloc has failed, you haven't lost your original memory, like in this answer: stackoverflow.com/a/44789446/1212725
– bruceg
Nov 21 '18 at 2:21
@Swordfish, it's a generic type, but in my program it's an integer (int
)
– Michal Dvořák
Nov 21 '18 at 11:03
Updated my question, checking the realloc isNULL
didn't help.
– Michal Dvořák
Nov 21 '18 at 11:20
Are you sure thatinternal_array
holds eitherNULL
or a valid pointer value returned bymalloc()
,calloc()
,realloc(NULL, ...)
before you callrealloc()
with it as the firest parameter?
– Swordfish
Nov 21 '18 at 13:42
|
show 2 more comments
1
How do you determine that it leaks? What do you do ifrealloc()
fails? Curious: what isT
?
– Swordfish
Nov 21 '18 at 2:08
3
The correct way to call realloc is to save the return value in a temporary variable and check it for NULL. That way if realloc has failed, you haven't lost your original memory, like in this answer: stackoverflow.com/a/44789446/1212725
– bruceg
Nov 21 '18 at 2:21
@Swordfish, it's a generic type, but in my program it's an integer (int
)
– Michal Dvořák
Nov 21 '18 at 11:03
Updated my question, checking the realloc isNULL
didn't help.
– Michal Dvořák
Nov 21 '18 at 11:20
Are you sure thatinternal_array
holds eitherNULL
or a valid pointer value returned bymalloc()
,calloc()
,realloc(NULL, ...)
before you callrealloc()
with it as the firest parameter?
– Swordfish
Nov 21 '18 at 13:42
1
1
How do you determine that it leaks? What do you do if
realloc()
fails? Curious: what is T
?– Swordfish
Nov 21 '18 at 2:08
How do you determine that it leaks? What do you do if
realloc()
fails? Curious: what is T
?– Swordfish
Nov 21 '18 at 2:08
3
3
The correct way to call realloc is to save the return value in a temporary variable and check it for NULL. That way if realloc has failed, you haven't lost your original memory, like in this answer: stackoverflow.com/a/44789446/1212725
– bruceg
Nov 21 '18 at 2:21
The correct way to call realloc is to save the return value in a temporary variable and check it for NULL. That way if realloc has failed, you haven't lost your original memory, like in this answer: stackoverflow.com/a/44789446/1212725
– bruceg
Nov 21 '18 at 2:21
@Swordfish, it's a generic type, but in my program it's an integer (
int
)– Michal Dvořák
Nov 21 '18 at 11:03
@Swordfish, it's a generic type, but in my program it's an integer (
int
)– Michal Dvořák
Nov 21 '18 at 11:03
Updated my question, checking the realloc is
NULL
didn't help.– Michal Dvořák
Nov 21 '18 at 11:20
Updated my question, checking the realloc is
NULL
didn't help.– Michal Dvořák
Nov 21 '18 at 11:20
Are you sure that
internal_array
holds either NULL
or a valid pointer value returned by malloc()
, calloc()
, realloc(NULL, ...)
before you call realloc()
with it as the firest parameter?– Swordfish
Nov 21 '18 at 13:42
Are you sure that
internal_array
holds either NULL
or a valid pointer value returned by malloc()
, calloc()
, realloc(NULL, ...)
before you call realloc()
with it as the firest parameter?– Swordfish
Nov 21 '18 at 13:42
|
show 2 more comments
1 Answer
1
active
oldest
votes
You are reading the error wrong:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
It clearly says that the memory allocated at ArrayList<int>::changeSize(int)
is the memory that leaks. It does not say what operation caused it to leak.
This means that changeSize(int)
is ok. The problem lies elsewhere. You must make sure that the rule of 5 is followed:
- Destructor frees the memory.
- Copy constructor copies contents of
internal_array
, not the pointer. - Assignment operator copies the contents, and not the pointer. Consider the copy-and-swap idiom.
- Move constructor copies the pointer, but nullifies the other object.
- Move assignment swaps the pointers, or assigns one pointer and frees the other.
The bug is probably due to missing, or wrong, one of the above. A good way to make it easier to catch such bugs during compile time, is to use std::unique_ptr with a custom deleter instead of freeing manually.
Please note that your code will crash and/or leak memory with anything complex, like T=vector or T=big num. You can add static_assert(std::is_trivial<T>::value);
to make sure it is not instantiated with, e.g., std::map
.
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%2f53404321%2fwhere-does-this-memory-leak-come-from%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You are reading the error wrong:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
It clearly says that the memory allocated at ArrayList<int>::changeSize(int)
is the memory that leaks. It does not say what operation caused it to leak.
This means that changeSize(int)
is ok. The problem lies elsewhere. You must make sure that the rule of 5 is followed:
- Destructor frees the memory.
- Copy constructor copies contents of
internal_array
, not the pointer. - Assignment operator copies the contents, and not the pointer. Consider the copy-and-swap idiom.
- Move constructor copies the pointer, but nullifies the other object.
- Move assignment swaps the pointers, or assigns one pointer and frees the other.
The bug is probably due to missing, or wrong, one of the above. A good way to make it easier to catch such bugs during compile time, is to use std::unique_ptr with a custom deleter instead of freeing manually.
Please note that your code will crash and/or leak memory with anything complex, like T=vector or T=big num. You can add static_assert(std::is_trivial<T>::value);
to make sure it is not instantiated with, e.g., std::map
.
add a comment |
You are reading the error wrong:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
It clearly says that the memory allocated at ArrayList<int>::changeSize(int)
is the memory that leaks. It does not say what operation caused it to leak.
This means that changeSize(int)
is ok. The problem lies elsewhere. You must make sure that the rule of 5 is followed:
- Destructor frees the memory.
- Copy constructor copies contents of
internal_array
, not the pointer. - Assignment operator copies the contents, and not the pointer. Consider the copy-and-swap idiom.
- Move constructor copies the pointer, but nullifies the other object.
- Move assignment swaps the pointers, or assigns one pointer and frees the other.
The bug is probably due to missing, or wrong, one of the above. A good way to make it easier to catch such bugs during compile time, is to use std::unique_ptr with a custom deleter instead of freeing manually.
Please note that your code will crash and/or leak memory with anything complex, like T=vector or T=big num. You can add static_assert(std::is_trivial<T>::value);
to make sure it is not instantiated with, e.g., std::map
.
add a comment |
You are reading the error wrong:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
It clearly says that the memory allocated at ArrayList<int>::changeSize(int)
is the memory that leaks. It does not say what operation caused it to leak.
This means that changeSize(int)
is ok. The problem lies elsewhere. You must make sure that the rule of 5 is followed:
- Destructor frees the memory.
- Copy constructor copies contents of
internal_array
, not the pointer. - Assignment operator copies the contents, and not the pointer. Consider the copy-and-swap idiom.
- Move constructor copies the pointer, but nullifies the other object.
- Move assignment swaps the pointers, or assigns one pointer and frees the other.
The bug is probably due to missing, or wrong, one of the above. A good way to make it easier to catch such bugs during compile time, is to use std::unique_ptr with a custom deleter instead of freeing manually.
Please note that your code will crash and/or leak memory with anything complex, like T=vector or T=big num. You can add static_assert(std::is_trivial<T>::value);
to make sure it is not instantiated with, e.g., std::map
.
You are reading the error wrong:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7f0c9d1b5f40 in realloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdef40)
#1 0x557b3b693fb2 in ArrayList<int>::changeSize(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2fb2)
#2 0x557b3b6939c4 in ArrayList<int>::Add(int) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x29c4)
#3 0x557b3b692671 in readInput(ArrayList<int>*) (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x1671)
#4 0x557b3b693339 in main (/media/mdvorak/Maxtor/Vysoká Škola/PA1/progtest5/a.out+0x2339)
#5 0x7f0c9cd07b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
It clearly says that the memory allocated at ArrayList<int>::changeSize(int)
is the memory that leaks. It does not say what operation caused it to leak.
This means that changeSize(int)
is ok. The problem lies elsewhere. You must make sure that the rule of 5 is followed:
- Destructor frees the memory.
- Copy constructor copies contents of
internal_array
, not the pointer. - Assignment operator copies the contents, and not the pointer. Consider the copy-and-swap idiom.
- Move constructor copies the pointer, but nullifies the other object.
- Move assignment swaps the pointers, or assigns one pointer and frees the other.
The bug is probably due to missing, or wrong, one of the above. A good way to make it easier to catch such bugs during compile time, is to use std::unique_ptr with a custom deleter instead of freeing manually.
Please note that your code will crash and/or leak memory with anything complex, like T=vector or T=big num. You can add static_assert(std::is_trivial<T>::value);
to make sure it is not instantiated with, e.g., std::map
.
answered Nov 21 '18 at 14:26
Michael VekslerMichael Veksler
2,6071515
2,6071515
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%2f53404321%2fwhere-does-this-memory-leak-come-from%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
1
How do you determine that it leaks? What do you do if
realloc()
fails? Curious: what isT
?– Swordfish
Nov 21 '18 at 2:08
3
The correct way to call realloc is to save the return value in a temporary variable and check it for NULL. That way if realloc has failed, you haven't lost your original memory, like in this answer: stackoverflow.com/a/44789446/1212725
– bruceg
Nov 21 '18 at 2:21
@Swordfish, it's a generic type, but in my program it's an integer (
int
)– Michal Dvořák
Nov 21 '18 at 11:03
Updated my question, checking the realloc is
NULL
didn't help.– Michal Dvořák
Nov 21 '18 at 11:20
Are you sure that
internal_array
holds eitherNULL
or a valid pointer value returned bymalloc()
,calloc()
,realloc(NULL, ...)
before you callrealloc()
with it as the firest parameter?– Swordfish
Nov 21 '18 at 13:42