I'm trying to enumerate local users on Mac os.
It works correctly, but i think that there is
some resource leak. I can't understand that.
Profiling says that there are no memory leaks,
but memory usage are constantly grows (Memory Report
chart at XCode). In my case since 2.7M to 4.9M (5 * 1000 iterations).
Can anybody say what is wrong with my code.
Are there any leaks or the behaviour is normal?
This is a simple c++ command line tool project
with Objective-c code with default build settings (XCode 5):
/////////////////////////////////////////////
// main.cpp
#include "test.h"
#include <iostream>
#include <thread>
int main(int argc, const char * argv[])
{
//for (int i = 0; i < 1000; ++i)
for (int i = 0; i < 5; ++i)
{
std::cout << "Iteration # " << i << std::endl;
for (int j = 0; j < 1000; ++j)
{
Execute();
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
/////////////////////////////////////////////
// test.mm
#import <Collaboration/Collaboration.h>
#import <CoreServices/CoreServices.h>
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SCDynamicStore.h>
#import <SystemConfiguration/SCDynamicStoreCopySpecific.h>
#include <iostream>
void Execute()
{
CSIdentityAuthorityRef identityAuthority = CSGetLocalIdentityAuthority();
if (!identityAuthority)
{
std::cout << "Failed to get identity authority." << std::endl;
return;
}
CSIdentityQueryRef usersQuery(CSIdentityQueryCreate(nil, kCSIdentityClassUser, identityAuthority));
if (!usersQuery)
{
std::cout << "Failed to create query." << std::endl;
return;
}
/////////////////////////////////////////////////
// Without CSIdentityQueryExecute(usersQuery, 0, nil) - everething is ok.
/////////////////////////////////////////////////
if (!CSIdentityQueryExecute(usersQuery, 0, nil))
{
std::cout << "Failed to execute query." << std::endl;
return;
}
CFRelease(usersQuery);
}
#ifndef __MY_TEST_H__
#define __MY_TEST_H__
void Execute();
#endif
Try to execute the CFRelease before every return since some iterations are not releasing the data.
I just ran this program, and I'm not seeing any memory growth. I slightly simplified it to be a single-file C++ program (currently it's a mix of C++ and ObjC++).
You do have a memory mistake, but I would only expect it to cause a leak if you were getting errors. This block leaks the query:
if (!CSIdentityQueryExecute(usersQuery, 0, nil))
{
std::cout << "Failed to execute query." << std::endl;
return;
}
You should either not return here (you don't technically need to), or you should include a CFRelease(usersQuery) before the return. But again, if this were the problem, you'd see lots of "Failed to execute query" log messages.
Related
I've searched extensively but there seems not to be a satisfying answer to this question online. So I'm posting again this problem in case someone has found a solution.
I have written a C++ code that is supposed to call some Matlab code. I have compiled all my Matlab files using the following command:
mcc -N -W cpplib:libRTR2 -T link:lib RTR.m -v
I have included the header, DLL and LIB files created by above command in the 'Header Files'for my Visual Studio project. I have also includde mclmcrrt.lib, mclmcrrt.h and mclcppclass.h in the same.
Here is my C++ code:
#define BZZ_COMPILER 3
#include <stdint.h>
#include "./hpp/BzzMath.hpp"
#include "libRTR2.h"
#include <iostream>
#include "mclmcrrt.h"
#include "mclcppclass.h"
double RTRtest(BzzVector &x)
{
x(1);
mwArray out(1,1);
try {
// create input
double a[] = { x[1] };
mwArray in1(1, 1, mxDOUBLE_CLASS, mxREAL);
in1.SetData(a, 1);
// call function
RTR(1, out, in1);
// show result
std::cout << "objFun" << std::endl;
std::cout << out << std::endl;
double F[1];
out.GetData(F, 1);
for (int i = 0; i<1; i++) {
std::cout << F[i] << " " << std::endl;
}
}
catch (const mwException& e) {
std::cerr << e.what() << std::endl;
return -2;
}
catch (...) {
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
// cleanup
return out;
}
int optim()
{
if (!mclInitializeApplication(NULL, 0)) {
std::cerr << "could not initialize the application" << std::endl;
mclGetLastErrorMessage();
return -1;
}
if (!libRTR2Initialize()) {
std::cerr << "Could not initialize the library" << std::endl;
return -1;
}
bzzFilePrint("BzzRobustMinimization.txt");
BzzVector Xmin(1, 2000.);
BzzVector Xmax(1, 5000.);
BzzVector X0(1, 2000.);
double F0 = RTRtest(X0);
BzzMinimizationRobust m(X0, F0, RTRtest, Xmin, Xmax);
m();
m.BzzPrint("Results");
libRTR2Terminate();
mclTerminateApplication();
}
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)optim, 0, NULL);
}
And when I try to debug it I obtain this error:
Access Violation Error
I know it is related probably to trying to pass a null pointer to one of my functions, but being no expert in C++ I'm struggling to find where the error lies. Any help is greatly appreciated!
I'm currently learning c++ from scratch, I've previously developed apps with C# using Visual Studio but I'm a total noob with C++, I'm trying to make a small console exe that releases and renews the ip while practicing using headers and differents .cpp files.
The issue is that when I run the local windows debugger from visual studio 2015 the code runs perfectly and does everything I'm trying to. But when I build and try to run the .exe file it goes into an infinite loop stating endlessly the output from the std::cout <<"Realizando ipconfig Release", I have localized the issue to when it tries to run the system("ipconfig /release"). Why does this happen? and How can I fix it?
This is the header
#pragma once
#ifndef HeaderIp
#define HeaderIp
int Release();
int Renew();
#endif // !HeaderIp
This is the release.cpp
#include <stdlib.h>
int Release()
{
if (system(nullptr)==0)
{
return 0;
}
else
{
system("ipconfig /release");
return 1;
}
}
This is the renew.cpp
#include <stdlib.h>;
int Renew()
{
if (system(nullptr)==0)
{
return 0;
}
else
{
system("ipconfig /renew");
return 1;
}
}
and finally this is the ipconfig.cpp
#include <iostream>
#include <stdlib.h>
#include "HeaderIp.h"
#include <stdio.h>
int main()
{
std::cout << "Realizando ipconfig Release" << std::endl;
int i = 0; //Bit de informacion de status de CPU
i = Release();
if (i == 0)
{
std::cout << "Error al liberar IP" << std::endl;
system("pause");
exit;
}
else
{
std::cout << "Ip Liberado correctamente" << std::endl;
}
i = Renew();
if (i == 0)
{
std::cout << "Error al renovar IP" << std::endl;
system("pause");
exit;
}
else
{
std::cout << "Ip renovado correctamente" << std::endl;
}
system("pause");
return 0;
}
It's unusual, and indeed generally discouraged to use system in C++. If you were to manage DHCP leases using IpReleaseAddress and IpRenewAddress, instead, you might find your problem disappears.
You can use std::cin.sync() instead of system("pause"), too.
exit; probably doesn't do what you want it to, as you're only referring to the function, you're not calling it, so... it'll do nothing.
The semicolon in #include <stdlib.h>; is an error, and you should be including <cstdlib> and <cstdio> rather than <stdlib.h> and <stdio.h>.
I'm writing a small demo with tesseract APIs to run in parallel via OpenMp; it is basically an example taken from tesseract APIs usage page, with some openmp flavour added on it.
The executable takes two arguments: a tif file and an integer for the page to be ocrized.
I'm compiling like this:
clang-omp++ -o tessapi-quality tessapi-quality.cpp -<TESSERACT_FLAGS> -O3 -fopenmp -g.
The problem I'm facing is that it works most of the time, but one over five - more or less - it throws a seg fault.
I tried and debug with gdb, but couldn't find out, 'cause it dies sometimes on a tesseract baseapi function, sometimes on another.
Unfortunately I cannot install valgrind on the machine where I'm working on now.
I'm aware that it's not handy to be tested from anyone who has not tesseract installed, but maybe I'm missing something big in the code and you can help me just taking a look.
This is the code:
#include <stdlib.h>
#include <iostream>
#include <leptonica/allheaders.h>
#include <omp.h>
#include <sys/time.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <tesseract/api/baseapi.h>
void getCompImage(const char* filename, int page){
Pix* image;
Pixa** pixa;
int** blockids;
image = pixReadTiff(filename, page);
int num_threads = 4;
omp_set_num_threads(num_threads);
#pragma omp parallel
{
tesseract::TessBaseAPI *papi = new tesseract::TessBaseAPI();
if (papi->Init(NULL, "eng")) {
#pragma omp critical
{
std::cout << "Could not initialize tesseract " << '\n';
}
exit(1);
}
papi->SetImage(image);
Boxa* boxes = papi->GetComponentImages(tesseract::RIL_TEXTLINE, true, pixa, blockids);
#pragma omp barrier
#pragma omp for schedule(static)
for (int i = 0; i < boxes->n; i++) {
BOX* box = boxaGetBox(boxes, i, L_CLONE);
papi->SetRectangle(box->x, box->y, box->w, box->h);
char* ocrResult = papi->GetUTF8Text();
int my_thread = omp_get_thread_num();
#pragma omp critical
{
std::cout << "Thread: " << my_thread << " Page: " << page << " Box[" << i << "] text: " << ocrResult << "\n";
}
}
// Destroy used object and release memory
papi->End();
}
pixDestroy(&image);
}
int main(int argc, char *argv[])
{
if (argc != 3){
printf("Type the (tiff) file name to OCRize\n"
"Then the page in the file to OCRize (first page=0, second=1 etc..)\n\n");
exit(-1);
}
int page = atoi(argv[2]);
getCompImage(argv[1], page);
return 0;
}
I'm trying to write a simple fingerprint scanning program in c++ using libfprint, however it intermittently segfaults when run. Valgrind says the error is in the call to fp_enroll_finger which is consistent with my debugging, however beyond that I have absolutely no idea what is causing this error. Some of the times the program is run its fine, but some times it seems to consistently segfault for a period of time whenever the program is run?
Heres the code:
#include <iostream>
extern "C"
{
#include <libfprint/fprint.h>
}
using namespace std;
fp_dev * fpdev;
fp_print_data ** fpdata;
bool createDevice();
int main(int argc, char **argv)
{
int r = fp_init();
if(r != 0)
{
return r;
}
while(createDevice())
{
cout << "Scan right index finger" << endl;
int enrollStatus = fp_enroll_finger(fpdev, fpdata);
if(enrollStatus != 1)
{
cout << "Bad scan" << endl;
fp_dev_close(fpdev);
}
else
{
cout << "Good scan" << endl;
fp_print_data_save(fpdata[0], RIGHT_INDEX);
break;
}
}
if(fpdev != NULL)
{
fp_dev_close(fpdev);
}
fp_exit();
return 0;
}
bool createDevice()
{
fp_dscv_dev ** listOfDiscoveredDevs;
fp_dscv_dev * discoveredDevice;
listOfDiscoveredDevs = fp_discover_devs();
discoveredDevice = listOfDiscoveredDevs[0];
if(discoveredDevice != NULL)
{
cout << "Device found" << endl;
fpdev = fp_dev_open(discoveredDevice);
}
else
{
cout << "No device found" << endl;
return false;
}
fp_dscv_devs_free(listOfDiscoveredDevs);
return true;
}
You need to define fpdev and fpdata as:
fp_dev * fpdev;
fp_print_data * fpdata;
And use them as:
fp_enroll_finger(&fpdev, &fpdata);
Also don't forget to free fpdata when you no longer need it with fp_print_data_free
fp_dev * fpdev;
fp_print_data ** fpdata;
Will create 2 uninitialised pointers pointing to random memory location and leading to segfault once fp_enroll_finger will attempt to acces that location.
Checking fp_enroll_finger return value can be useful as well.
I think I must be assuming something from the name boost::interprocess that is not true.
The documents repeat that named_mutex is global here.
I am unable to make it work though. Two copies of the same executable should be run at the same time, and I expect that a named mutex in a library named boost::interprocess might actually BLOCK sometimes. It doesn't. It also doesn't prevent data file corruption in the code below.
Here's some code from the boost docs:
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <fstream>
#include <iostream>
#include <cstdio>
int main ()
{
using namespace boost::interprocess;
try{
struct file_remove
{
file_remove() { std::remove("file_name"); }
~file_remove(){ std::remove("file_name"); }
} file_remover;
struct mutex_remove
{
mutex_remove() { named_mutex::remove("fstream_named_mutex"); }
~mutex_remove(){ named_mutex::remove("fstream_named_mutex"); }
} remover;
//Open or create the named mutex
named_mutex mutex(open_or_create, "fstream_named_mutex");
std::ofstream file("file_name");
for(int i = 0; i < 10; ++i){
//Do some operations...
//Write to file atomically
scoped_lock<named_mutex> lock(mutex);
file << "Process name, ";
file << "This is iteration #" << i;
file << std::endl;
}
}
catch(interprocess_exception &ex){
std::cout << ex.what() << std::endl;
return 1;
}
return 0;
Here's what I did to it so I could prove to myself the mutex was doing something:
#include <windows.h>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <cstdio>
int main (int argc, char *argv[])
{
srand((unsigned) time(NULL));
using namespace boost::interprocess;
try{
/*
struct file_remove
{
file_remove() { std::remove("file_name"); }
~file_remove(){ std::remove("file_name"); }
} file_remover;
*/
struct mutex_remove
{
mutex_remove() { named_mutex::remove("fstream_named_mutex"); }
~mutex_remove(){ named_mutex::remove("fstream_named_mutex"); }
} remover;
//Open or create the named mutex
named_mutex mutex(open_or_create, "fstream_named_mutex");
std::ofstream file("file_name");
for(int i = 0; i < 100; ++i){
//Do some operations...
//Write to file atomically
DWORD n1,n2;
n1 = GetTickCount();
scoped_lock<named_mutex> lock(mutex);
n2 = GetTickCount();
std::cout << "took " << (n2-n1) << " msec to acquire mutex";
int randomtime = rand()%10;
if (randomtime<1)
randomtime = 1;
Sleep(randomtime*100);
std::cout << " ... writing...\n";
if (argc>1)
file << argv[1];
else
file << "SOMETHING";
file << " This is iteration #" << i;
file << std::endl;
file.flush(); // added in case this explains the corruption, it does not.
}
}
catch(interprocess_exception &ex){
std::cout << "ERROR " << ex.what() << std::endl;
return 1;
}
return 0;
}
Console Output:
took 0 msec to acquire mutex ... writing...
took 0 msec to acquire mutex ... writing...
took 0 msec to acquire mutex ... writing...
took 0 msec to acquire mutex ... writing...
Also, the demo writes to a file, which if you run two copies of the program will be missing some data.
I expect that if I delete file_name and run two copies of the program, I should get interleaved writes to file_name containing 100 rows from each instance.
(Note, that the demo code is clearly not using an ofstream in append mode, instead it simply rewrites the file each time this program runs, so if we wanted a demo to show two processes writing to a file, I'm aware of that reason why it wouldn't work, but what I did expect is for the above code to be a feasible demonstration of mutual exclusion, which it is not. Also calls to a very handy and aptly named ofstream::flush() method could have been included, and weren't.)
Using Boost 1.53 on Visual C++ 2008
It turns out that Boost is a wonderful library, and it code examples interspersed in the documentation may sometimes be broken. At least the one for boost::interprocess::named_mutex in the docs is not functional on Windows systems.
*Always deleting a mutex as part of the demo code causes the mutex to not function. *
That should be commented in the demo code at the very least. It fails to pass the "principle of least amazement", although I wondered why it was there, I thought it must be idiomatic and necessary, it's idiotic and unnecessary, in actual fact. Or if it's necessary it's an example of what Joel Spolsky would call a leaky abstraction. If mutexes are really filesystem points under C:\ProgramData in Windows I sure don't want to know about it, or know that turds get left behind that will break the abstraction if I don't detect that case and clean it up. (Sure smells like posix friendly semantics for mutexes in Boost have caused them to use a posix-style implementation instead of going to Win32 API directly and implementing a simple mutex that has no filesystem turds.)
Here's a working demo:
#include <windows.h>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <fstream>
#include <iostream>
#include <cstdio>
#include <windows.h>
int main (int argc, char *argv[])
{
srand((unsigned) time(NULL));
using namespace boost::interprocess;
try{
/*
// UNCOMMENT THIS IF YOU WANT TO MAKE THIS DEMO IMPOSSIBLE TO USE TO DEMO ANYTHING
struct file_remove
{
file_remove() { std::remove("file_name"); }
~file_remove(){ std::remove("file_name"); }
} file_remover;
// UNCOMMENT THIS IF YOU WANT TO BREAK THIS DEMO HORRIBLY:
struct mutex_remove
{
mutex_remove() { named_mutex::remove("fstream_named_mutex"); }
~mutex_remove(){ named_mutex::remove("fstream_named_mutex"); }
} remover;
*/
//Open or create the named mutex
named_mutex mutex(open_or_create, "fstream_named_mutex");
std::ofstream file("file_name", std::ios_base::app );
int randomtime = 0;
for(int i = 0; i < 100; ++i){
//Do some operations...
//Write to file atomically
DWORD n1,n2;
n1 = GetTickCount();
{
scoped_lock<named_mutex> lock(mutex);
n2 = GetTickCount();
std::cout << "took " << (n2-n1) << " msec to acquire mutex";
randomtime = rand()%10;
if (randomtime<1)
randomtime = 1;
std::cout << " ... writing...\n";
if (argc>1)
file << argv[1];
else
file << "SOMETHING";
file << "...";
Sleep(randomtime*100);
file << " This is iteration #" << i;
file << std::endl;
file.flush();
}
Sleep(randomtime*100); // let the other guy in.
}
}
catch(interprocess_exception &ex){
std::cout << "ERROR " << ex.what() << std::endl;
return 1;
}
return 0;
}
I would love critques and edits on this answer, so that people will have a working demo of using this named mutex .
To use the demo:
- Build it and run two copies of it. Pass a parameter in so you can see which instance wrote which lines (start myexename ABC and start myexename DEF from a command prompt in windows)
- If it's your second run, delete any stray output named "file_name" if you don't want the second run appended to the first.