I'm trying to use instruments for the first time. So, I wrote a small C program to detect memory leaks in instruments.
Code:
#include <stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main()
{
int *temp = NULL;
temp = (int*)malloc(100*sizeof(int));
for (int i = 0; i<100; ++i) {
temp[i] = i;
}
printf("%d", *(temp+1));
printf("Hello ");
temp = NULL;
usleep(10000000);
printf("%d", *(temp+1));
}
When I use free(temp)
In the 1st pic, there are no leaks but in the below panel we can see the allocated details.
In the 2nd pic, there are no leaks but in the below panel we can see there are no details.
Why is that? Can anybody explain the output(top and below panels)?
Thank you!
Update:
You mean like this?
int main()
{
char **temp = NULL;
temp = (char**)malloc(100*sizeof(char*));
for (int i = 0; i<100; ++i) {
temp[i] = (char *)malloc(100*sizeof(char));
temp[i]=NULL;
usleep(2000000);
}
}
P.S I tagged C++ because I think the above code can be written in C++ also. Please remove the tag if I'm wrong.
There is no problem with your code. It creates a memory leak as you expected. The problem(actually its good) is with the Xcode.
Xcode optimises your code to remove all the memory leaks. Thats why instruments not showing any memory leaks.
To see your memory leaks, disable the optimisations in the Xcode.
Select None [-O0] to disable all the optimisations.
You use intstruments to profile the final production code. So, don't change the Release settings. You may forget to change it back and your program will not be optimised.
Instead edit the scheme of Profile from Release to Debug. Doing this you can always get optimised code for the Release.
1). Click on executable icon
2). Click on Edit Scheme.
3). Change the Build Configuration to Debug.
Now, whenever you profile your code, you will get all the errors as your code is not optimised.
To profile your release code, change it back to Release in the Build Configuration.
Related
I'm trying to use realloc function in C, to dynamically operate on a char array of strings (char**).
I usually get a realloc():invalid old size error after 41st cicle of the for loop and I really can't understand why.
So, thanks to everyone who will help me ^-^
[EDIT] I'm trying to make the post more clear and following your advices, as a "new active member" of this community, so thank you all!
typedef struct _WordsOfInterest { // this is in an header file containing just
char **saved; // the struct and libraries
int index;
} wordsOfInterest;
int main() {
char *token1, *token2, *save1 = NULL, file[LEN], *temp, *word, **tokenArr;
int n=0, ch,ch2, flag=0, size, init=0,position,currEdit,init2=0,tempEdit,size_arr=LEN,
oldIndex=0,totalIndex=0,*editArr,counterTok=0;
wordsOfInterest toPrint;
char **final;
toPrint.index = 0;
toPrint.saved = malloc(sizeof(char*)*LEN);
editArr = malloc(sizeof(int)*LEN);
tokenArr = malloc(sizeof(char*)*LEN);
final = malloc(sizeof(char*)*1);
// external for loop
for(...) {
tokenArr[counterTok] = token1;
// internal while loop
while(...) {
// some code here surely not involved in the issue
} else {
if(init2 == 0) {
currEdit = config(token1,token2);
toPrint.saved[toPrint.index] = token2;
toPrint.index++;
init2 = 1;
} else {
if((abs((int)strlen(token1)-(int)strlen(token2)))<=currEdit) {
if((tempEdit = config(token1,token2)) == currEdit) {
toPrint.saved[toPrint.index] = token2;
toPrint.index++;
if(toPrint.index == size_arr-1) {
size_arr = size_arr*2;
toPrint.saved = realloc(toPrint.saved, size_arr);
}
} else if((tempEdit = config(token1,token2))<currEdit) {
freeArr(toPrint, size_arr);
toPrint.saved[toPrint.index] = token2;
toPrint.index++;
currEdit = tempEdit;
}
}
}
flag = 0;
word = NULL;
temp = NULL;
freeArr(toPrint, size_arr);
}
}
editArr[counterTok] = currEdit;
init2 = 0;
totalIndex = totalIndex + toPrint.index + 1;
final = realloc(final, (sizeof(char*)*totalIndex));
uniteArr(toPrint, final, oldIndex);
oldIndex = toPrint.index;
freeArr(toPrint,size_arr);
fseek(fp2,0,SEEK_SET);
counterTok++;
}
You start with final uninitialized.
char **final;
change it to:
char **final = NULL;
Even if you are starting with no allocation, it needs a valid value (e.g. NULL) because if you don't initialize a local variable to NULL, it gets garbage, and realloc() will think it is reallocating a valid chunk of memory and will fail into Undefined Behaviour. This is probably your problem, but as you have eliminated a lot of code in between the declaration and the first usage of realloc, whe cannot guess what is happening here.
Anyway, if you have indeed initialized it, I cannot say, as you have hidden part of the code, unlistening the recommendation of How to create a Minimal, Reproducible Example
.
There are several reasons (mostly explained there) to provide a full but m inimal, out of the box, failing code. This allows us to test that code without having to provide (and probably solving, all or part) the neccesary code to make it run. If you only post a concept, you cannot expect from us complete, full running, and tested code, degrading strongly the quality of SO answers.
This means you have work to do before posting, not just eliminating what you think is not worth mentioning.
You need to build a sample that, with minimum code, shows the actual behaviour you see (a nonworking complete program) This means eliminating everything that is not related to the problem.
You need (and this is by far more important) to, before sending the code, to test it at your site, and see that it behaves as you see at home. There are many examples that, when eliminated the unrelated code, don't show the commented behaviour.
...and then, without touching anymore the code, send it as is. Many times we see code that has been touched before sending, and the problem dissapeared.
If we need to build a program, we will probably do it with many other mistakes, but not yours, and this desvirtuates the purpose of this forum.
Finally, sorry for the flame.... but it is necessary to make people read the rules.
I'm currently using Clion 2017.3.4 in C99.
while trying to run and debug my program, the debugger jumps into 'disassembly view', and I want to know what the problem is.
basically, the function gets a season(type), a input string (season_info), and an index, that points to a different place in the input string.
the function should return the year as an integer, while the input is a string
the disassembly view is showen when I step into the free() line.
any ideas what the problem is?
and generally what the disassembly view means?
int GetSeasonYear(Season season, const char* season_info, int *index){
char* tmp_str = GetStringByLine(season_info, index);
if(tmp_str == NULL){
SeasonDestroy(season);
return 0;
}
season->season_year = atoi(tmp_str);
free(tmp_str);
return 1;
}
this is the function used inside the GetSeasonYear function(although I check and it works fine).
char* GetStringByLine(const char* season_info, int* index){ // change back to static
int i = 0;
while(season_info[i] != '\n'){
i++;
}
char* tmp_str = malloc(sizeof(char)*(i+1));
if(tmp_str == NULL){
return NULL;
}
memcpy(tmp_str, season_info, sizeof(char)*i);
tmp_str[i+1]='\0';
*index = i;
return tmp_str;
}
thanks
You are stepping into a function (free) for which you either
a) Do not have the source for
or
b) have the source for but the debuuger cannot locate it.
free() is a call to the system to release memory. It's more than likely been compiled with high optimisation and without debug symbols, so the best the debugger can do is just show you the disassembled machine code that it's executing.
Basically, it's normal. There's also very little benefit to stepping into calls like that.
I wrote this sample C program:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define SIZE 10
typedef struct _sampleStruct{
int f1;
double f2;
int f3[SIZE];
}sampleStruct;
sampleStruct g_s;
int main() {
sampleStruct s;
sampleStruct zeroed = {0};
s.f1 = g_s.f1 = 1;
s.f2 = g_s.f2 = 2.0;
for (int i = 0; i < SIZE; ++i) {
s.f3[i] = g_s.f3[i] = i*10;
}
memset(&s, 0, sizeof(sampleStruct));
printf("s: %d, g_s: %lf, zeroed: %d", s.f1, g_s.f2, zeroed.f3[3]);
return 0;
}
I'm using Eclipse Mars IDE and I want to debug this code.
the s and zeroed variables are shown in the variables tab.
however, the g_s (which is a global variable) is not shown there.
is there a way for me to see its fields and how they're changing etc.?
EDIT: just figured out there's a "add global variables" button but it is grayed, so I can't press it.
ok, so after some more googling about it I found this .
tl;dr - the problem was that I was using the default GDB(DSF) process launcher. apparently this is a known issue (more details in the link above).
what you should do to solve it:
go to Run-->Debug Configurations and check at the bottom of the opened window which debug launcher you are using. if it is the GDB(DSF) then press the "Select other..." link below it. In the opened window mark "Use configuration specific settings" and then choose a different launcher (in my case it is "Legacy Create Process Launcher").
now the "add global variables should not be gray and you can click it and choose the variables you want to watch.
leaving the question just in case someone will encounter the same problem.
I hope that you find this visual description helpful.
Click the Add Global Variables icon (green dot with eye-glasses above it):
Which is located under the Variables tab:
Here is a zoom-out of both:
I am using Visual Studio 2013, and taking a course in C programming and we started talking about memory bugs detaction, in particular memory leaks, and how to detect them using Valgrind on Linux.
I want to know if there is a way to detect such memory leaks using VS 2013. I tried searching online but it just leads to lots of articles and blogs and msdn posts and blogs with lots of words like dump files, and analizing them, etc which weird because:
1) It sounds so complex, convoluted and unintuitive it is actually hard to comprehend it.
2) The main reason this is weird is due to the fact that VS is the most advanced IDE around and Microsoft spends so much money on in, yet from what I have read it seems that there is no simple way to use VS to detect memory leaks - certainly no way that's as simple as Valgrind where I only have to compile the program and run the command
valgrind -leaks-check=yes ProgramName
and it simply prints to me all location it thinks there is a memory leak and describes the error (like not freeing memory after allocating it with malloc hence having "dead" memory after the program finishes, or accessing memory that's out of the array bounds)
So my question is how to use VS 2013 in order to achieve the same results and to find out First in high level if there are memory leaks in the program, and second - to detect in a simple manner where those leaks are- preferably without involving dump files (not that I know how to use them anyway in VS).
The answer I offer cannot be perfect as exhaustively explaining ALL features VS2013 etc. offer to find C/C++ heap hickups could be a book well sold. And not a very thin one for that matter.
First, things I will NOT cover:
sal.h - Semantic annotations (which are also used by MS tools, if provided).
Not EVERY _Crt* function available. Only a few to give the idea.
Additional steps an application designer might to add to their design for a "production quality" code base.
Having said that, here a piece of annotated code containing various bugs. Each bug is annotated with how it was possible to detect it by means of what VS2013 has to offer. Either at run time or at compile time or with static code analysis.
The compile time error sections are placed in comments, btw.
#include "stdafx.h"
#include <crtdbg.h>
#include <malloc.h>
#include <cstdint>
#include <cstdlib>
// This small helper class shows the _Crt functions (some of them)
// and keeps the other code less cluttered.
// Note: This is NOT what you should do in production code,
// as all those _Crt functions disappear in a release build,
// but this class does not disappear...
class HeapNeutralSection
{
_CrtMemState m_start;
public:
HeapNeutralSection()
{
_CrtMemCheckpoint(&m_start);
}
~HeapNeutralSection()
{
_CrtMemState now;
_CrtMemState delta;
_CrtMemCheckpoint(&now);
if (_CrtMemDifference(&delta, &m_start, &now))
{
// This code section is not heap neutral!
_CrtMemDumpStatistics(&delta);
_CrtDumpMemoryLeaks();
_ASSERTE(false);
}
}
};
static void DoubleAllocationBug()
{
{
HeapNeutralSection hns;
uint32_t *rogue = (uint32_t*)malloc(sizeof(uint32_t));
if (NULL != rogue)
{
*rogue = 42; // Static Analysis without the NULL check: Dereferencing null pointer.
}
rogue = (uint32_t*)malloc(sizeof(uint32_t));
free(rogue);
// detected in destructor of HeapNeutralSection.
}
}
static void UninitializedPointerAccessBug()
{
// uint32_t *rogue;
// *rogue = 42; // C4700: uninitialized local variable 'rogue' used.
}
static void LeakBug()
{
{
HeapNeutralSection hns;
uint32_t *rogue = (uint32_t*)malloc(sizeof(uint32_t));
if (NULL != rogue)
{
*rogue = 42; // Static Analysis without the NULL check: Dereferencing null pointer.
}
}
}
static void InvalidPointerBug()
{
// Not sure if the C-compiler also finds this... one more reason to program C with C++ compiler ;)
// uint32_t *rogue = 234; // C2440: 'initalizing': cannot convert from 'int' to 'uint32_t *'
}
static void WriteOutOfRangeBug()
{
{
HeapNeutralSection hns;
uint32_t * rogue = (uint32_t*)malloc(sizeof(uint32_t));
if (NULL != rogue)
{
rogue[1] = 42; // Static analysis: warning C6200: Index '1' is out of valid index range '0' to '0' for non-stack buffer 'rogue'.
rogue[2] = 43; // Static analysis: warning C6200: Index '2' is out of valid index range '0' to '0' for non-stack buffer 'rogue'.
// warning C6386: Buffer overrun while writing to 'rogue': the writable size is '4' bytes, but '8' bytes might be written.
}
free(rogue); // We corrupted heap before. Next malloc/free should trigger a report.
/*
HEAP[ListAppend.exe]: Heap block at 0076CF20 modified at 0076CF50 past requested size of 28
ListAppend.exe has triggered a breakpoint.
*/
}
}
static void AccessAlreadyFreedMemoryBug()
{
{
HeapNeutralSection hns;
uint32_t * rogue = (uint32_t*)malloc(sizeof(uint32_t));
free(rogue);
*rogue = 42; // Static analysis: warning C6001: Using uninitialized memory 'rogue'.
}
}
int _tmain(int argc, _TCHAR* argv[])
{
// checks heap integrity each time a heap allocation is caused. Slow but useful.
_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF);
AccessAlreadyFreedMemoryBug();
WriteOutOfRangeBug();
UninitializedPointerAccessBug();
DoubleAllocationBug();
// _CrtDumpMemoryLeaks();
return 0;
}
Last not least, on Windows CE and in the DDKs (maybe also in the platform SDKs), there used to be the 2 static code checkers "prefast" and "prefix". But maybe they are now outdated.
Additionally, there are MS research projects, going a step beyond sal.h, such as:
VCC, which help finding concurrency bugs etc.
My program crashes on this function on the 7th line, when I call malloc() when I run in release mode I get the `Program.exe has stopped working message, and when I run in debugger, most of the time it succeeds but sometimes I get this message (especially on larger input):
MONOM* polynomialsProduct(MONOM* poly1, int size1, MONOM* poly2, int size2, int* productSize)
{
int i1, i2;
int phSize = 1, logSize = 0;
MONOM* product;
product = (MONOM*)malloc(phSize*sizeof(MONOM));
monomAllocationVerification(product);
for (i1 = 0; i1 < size1; i1++)
{
for (i2 = 0; i2 < size2; i2++)
{
if (logSize == phSize)
{
phSize *= 2;
product = (MONOM*)realloc(product,phSize*sizeof(MONOM));
monomAllocationVerification(product);
}
product[logSize].coefficient = poly1[i1].coefficient * poly2[i2].coefficient;
product[logSize].power = poly1[i1].power + poly2[i2].power;
logSize++;
}
}
mergeSort(product,logSize);
*productSize = sumMonomsWithSamePower(product, logSize);
return product;
}
I understand that I'm dealing with memory errors and problems, but is there any quick way to analyze my code and look for memory errors? I look at my code a dozen of times looking for this kind of errors and found nothing. (I didn't want to post the code here since its 420 lines long).
First of all, if heap corruption is detected on the first malloc, that means it happened earlier (not in this function or on previous pass). So the problem may lie outside this code.
However, the code also looks suspicious to me.
monomAllocationVerification has no size parameter, so it should work on one monom only, yet you call it only once after realloc on pointer to first element, despite having allocated space for quite a few monoms. Please clarify your decision.
It is a bit unclear why sumMonomsWithSamePower should return a size, and thus modify an array to store a value. May be a quirk, but still suspicious.
UPDATE
The problem was in other functions; a few reallocs with wrong size.
I would check the return value of malloc() and use perror() to describe what error has occured. Also here is the documentation for malloc() and perror().
if((product = (MONOM*)malloc(phSize*sizeof(MONOM))) == NULL)
{
perror("ERROR: Failed to malloc ");
return 1;
//perror() will display a system specified string to describe the error it may tell you the error
}
Also do you know the size of MONOM? If not add the following line to your code.
printf("MONOM SIZE = %i\n", sizeof(MONOM));