This code eats up to 1.5GB of memory and doesn't release it.
Why ? I'm expecting the memory to be freed after the call to the bigone function.
How to fix this ?
#include <iostream>
#include <jsoncpp/json/json.h>
#include <jsoncpp/json/value.h>
typedef unsigned char utiny;
void watchmem() {
char k;
std::cout << "watch memory consumption then press a key ";
std::cin >> k;
}
void bigone() {
Json::Value conf = Json::arrayValue;
for(utiny i = 0; i < 255; i++) {
for(utiny j = 0; j < 255; j++) {
for(utiny k = 0; k < 255; k++) {
conf[i][j][k] = 0;
}
}
}
}
int main(int argc, char **argv) {
bigone();
watchmem();
}
build:
g++ -std=c++11 -o chkmem chkmem.cpp -ljsoncpp && ./chkmem
Related
i want to create a link between two programs throughout the execs functions .
my idea is to create function then point on it by a function pointer then send it to the other program to test it . this is my first programenter code here
1- is this possible ?
2- how ?
i get this idea because i find each time to change the function name in the main function but the remainning still as it was but if i send a pointer function as a character pointer then my programm still as it without changing
#include <iostream>
#include <cstdlib>
#include <unistd.h>
using namespace std;
void
Random(int* ,const int );
int*
selection_sort(int *arr ,const int length)
{
int i = 0,minIndex{0},tmp{0},k{0};
while(i < length-1) // T(n-1) * C1
{
minIndex = i; // Tn * C2
for(int j = i+1 ; j < length ; j++ ) // som(Ti) from i = 0 to i = length-1 )*C3.
{
if((arr)[j] < (arr)[minIndex])
minIndex = j;
}
if(minIndex != i) // Tn * C4
{
tmp = (arr)[i];
(arr)[i] = (arr)[minIndex];
(arr)[minIndex] = tmp;
}
i++;
}
return arr;
}
void
Random(int* array,const int length)
{
srand(time(nullptr));
int i{-1};
while(i++ < length)
{
array[i] = rand()%100;
sleep(0.2);
}
}
int main(int argc,char* argv[])
{
int* (*ptr)(int*,const int ) = selection_sort;
execl("/home/hellios/Documents/Algorithms/sort_Algorithms/main",(char*)ptr,0); // complete the call
return EXIT_SUCCESS;
}
sort_Algorithms/main.c
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <ctime>
using namespace std;
void
Random(int* array,const int length);
int
main(int argc,char* argv[])
{
int* (*ptr)(int *,const int ) =(int* (*) (int*,const int)) argv[1];
int arr1[100],k{0},*arr;
Random(arr1,100);
arr = (*ptr)(arr1,100);
//selection_sort(arr,100);
cout<<"out of selection_sort"<<endl;
for(int j = 0 ; j < 100 ; j++ )
{
printf("[%d]\t", arr[j]);
if(!(++k %10))
cout<<endl;
}
printf("\n");
return EXIT_SUCCESS ;
}
void
Random(int* array,const int length)
{
srand(time(nullptr));
int i {-1};
while(i++ < length)
{
array[i] = rand()%100;
sleep(0.2);
}
}
Need some help with the problem.
When I compile my code below, it gives me this error:
error: invalid conversion from " int* " to " int "
I want to create a calculatePercentage function, so I can use the value when I call it.
void calculatePercentage(int voteResult[],int percentage[])
const int NO_OF_CANDIDATE = 10;
int main()
{
ifstream input("votes.txt",ios::in);
string candidates[NUMBER_OF_CANDIDATE];
int voteResult[NUMBER_OF_CANDIDATE];
int percentage[NUMBER_OF_CANDIDATE];
for (int i = 0; i < NUMBER_OF_CANDIDATE; i++) {
input >> candidates[i] >> voteResult[i];
}
calculatePercentage(voteResult, percentage); // error happened here.
return 0;
}
void calculatePercentage(int voteResult[],int percentage[])
{
int totalVotes = 0;
for (int i = 0; i < NUMBER_OF_CANDIDATE; i++)
{
totalVotes += votes[i];
}
for (int j = 0; j < NUMBER_OF_CANDIDATE; j++)
{
double wk_percentage = static_cast<double>{votes[j])/totalVotes;
percentage[j]=static_cast<int>(wk_percentage*100);
}
}
The code you posted has a bunch of errors.
calculatePercentage() definition is missing the closing ';'
probable name mismatch between NO_OF_CANDIDATE and NUMBER_OF_CANDIDATE
missing #include <fstream> (using ifstream)
missing #include <string>
missing std:: namespace before ifstream and string
votes not declared anywhere (should it be voteResult?)
wrong opening curly bracket instead in static_cast<double>{votes[j])/totalVotes;
...
Let alone the way you do calculation and parameter passing...
The following edited code should compile, not sure if it works as you expected:
#include <fstream>
#include <string>
void calculatePercentage(int voteResult[], int percentage[]);
const int NUMBER_OF_CANDIDATE = 10;
int main()
{
std::ifstream input("votes.txt");
std::string candidates[NUMBER_OF_CANDIDATE];
int voteResult[NUMBER_OF_CANDIDATE];
int percentage[NUMBER_OF_CANDIDATE];
for (int i = 0; i < NUMBER_OF_CANDIDATE; i++) {
input >> candidates[i] >> voteResult[i];
}
calculatePercentage(voteResult, percentage); // error happened here.
return 0;
}
void calculatePercentage(int voteResult[], int percentage[])
{
int totalVotes = 0;
for (int i = 0; i < NUMBER_OF_CANDIDATE; i++)
{
totalVotes += voteResult[i];
}
for (int j = 0; j < NUMBER_OF_CANDIDATE; j++)
{
double wk_percentage = static_cast<double>(voteResult[j]) / totalVotes;
percentage[j] = static_cast<int>(wk_percentage*100);
}
}
Also on Ideone.
Thanks for everyone's comment. I skipped some statements and made some typos when posting them. I fixed them as follows. The only error occurred is that still cannot convert " int* " from " int". Just don't know how to solve it.
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
void calculatePercentage(int voteResult[],int percentage[]);
const int NUMBER_OF_CANDIDATE = 10;
int main()
{
ifstream input("votes.txt",ios::in);
string candidates[NUMBER_OF_CANDIDATE];
int vote[NUMBER_OF_CANDIDATE];
int percentage[NUMBER_OF_CANDIDATE];
for (int i = 0; i < NUMBER_OF_CANDIDATE; i++) {
input >> candidates[i] >> vote[i];
}
calculatePercentage(voteResult, percentage); // error happened here.
return 0;
}
void calculatePercentage(int voteResult[],int percentage[])
{
int totalVotes = 0;
for (int i = 0; i < NUMBER_OF_CANDIDATE; i++)
{
totalVotes += votes[i];
}
for (int j = 0; j < NUMBER_OF_CANDIDATE; j++)
{
double wk_percentage = static_cast<double>(votes[j])/totalVotes;
percentage[j]=static_cast<int>(wk_percentage*100);
}
}
I have declared the following:
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
However when I open the MSVC debugger it shows the following:
This is how I added values to the vector:
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
Is this normal? Can I just ignore this? Or is this a problem?
Full code(the program is still not ready yet):
#include <iostream>
#include <vector>
#include "stdio.h"
const int NUMBER_OF_DIGITS = 16;
int checksum, tmp1, tmp2, tmp3, sum = 0;
std::vector<int> digits(NUMBER_OF_DIGITS);
std::vector<int> new_digits(NUMBER_OF_DIGITS);
int luhn_checksum(std::vector<int> cardnumber[NUMBER_OF_DIGITS]) {
//step 1: duouble every second number
for (int i = 1; i < NUMBER_OF_DIGITS; i += 2) {
new_digits[i] = digits[i] * 2;
if (new_digits[i] > 9) {
//if the product is larger than 9 we will add the two numbers together
//example: 9 * 2 = 18 so we will add 1 + 8 to get 9
tmp1 += new_digits[i] % 10;
new_digits[i] /= 10;
tmp1 = 0;
}
}
//step 2: sum all the values
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
checksum += new_digits[i];
}
return checksum;
}
void get_card_numbers(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
scanf("%d", &digits[i]);
}
}
void initialize(void) {
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
new_digits.push_back(0);
}
}
int main() {
initialize();
get_card_numbers();
printf("checksum is: %d\n", luhn_checksum(&digits));
std::cout << digits.size() << std::endl;
int x; scanf("%d", &x);
return 0;
}
The constructor you're using for digits is setting the size by specifying the count. So after calling push_back you've just added another 16 to the vector. Use a different constructor that doesn't set the count.
int _tmain(int argc, _TCHAR* argv[])
{
const int NUMBER_OF_DIGITS = 16;
std::vector<int> digits(NUMBER_OF_DIGITS);
//std::vector<int> digits;
int digitsLen = digits.size();
// Here is 16
for (int i = 0; i < NUMBER_OF_DIGITS; ++i) {
digits.push_back(0);
}
int digitsLen2 = digits.size();
// Here is 32
return 0;
}
Cleaned up your code a bit:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
static const size_t NUMBER_OF_DIGITS = 16;
class cards {
public:
cards();
void read();
int luhnChecksum() const;
private:
vector<int> digits;
};
cards::cards() : digits(NUMBER_OF_DIGITS, 0)
{
}
void cards::read() {
for_each(digits.begin(), digits.end(), [](int& i) { cin >> i; });
}
int cards::luhnChecksum() const {
vector<int> newdigits(digits.begin(), digits.end());
for (size_t i=1; i<NUMBER_OF_DIGITS; i += 2) {
newdigits[i] = digits[i] * 2;
if (newdigits[i] > 9) {
int tmp1 = newdigits[i] % 10;
newdigits[i] /= 10;
newdigits[i] += tmp1;
}
}
return accumulate(newdigits.begin(), newdigits.end(), 0);
}
int main() {
cards c;
c.read();
cout << "checksum = " << c.luhnChecksum() << endl;
return 0;
}
EDITS----------------I tried with gcc-4.8.1 and still the same error.-------------I am trying to implement a simple matrix multiplication example using pthreads via a shared library. But I get this error when I try to create a shared library:
g++ -shared -o libMatmul.so matmul.o
collect2: ld terminated with signal 11 [Segmentation fault], core dumped
Here is the code I am using:
matmul.h:
#ifndef matmul_h__
#define matmul_h__
#define SIZE 10
typedef struct {
int dim;
int slice;
} matThread;
int num_thrd;
int A[SIZE][SIZE], B[SIZE][SIZE], C[SIZE][SIZE];
int m[SIZE][SIZE];
extern void init_matrix(int m[SIZE][SIZE]);
extern void print_matrix(int m[SIZE][SIZE]);
extern void* multiply(void* matThread);
#endif
matmul.c:
extern "C"
{
#include <pthread.h>
#include <unistd.h>
}
#include <iostream>
#include "matmul.h"
using namespace std ;
matThread* s=NULL;
// initialize a matrix
void init_matrix(int m[SIZE][SIZE])
{
int i, j, val = 0;
for (i = 0; i < SIZE; i++)
for (j = 0; j < SIZE; j++)
m[i][j] = val++;
}
void print_matrix(int m[SIZE][SIZE])
{
int i, j;
for (i = 0; i < SIZE; i++) {
cout<<"\n\t|" ;
for (j = 0; j < SIZE; j++)
cout<<m[i][j] ;
cout<<"|";
}
}
// thread function: taking "slice" as its argument
void* multiply(void* param)
{
matThread* s = (matThread*)param; // retrive the slice info
int slice1=s->slice;
int D= s->dim=10;
int from = (slice1 * D)/num_thrd; // note that this 'slicing' works fine
int to = ((slice1+1) * D)/num_thrd; // even if SIZE is not divisible by num_thrd
int i,j,k;
cout<<"computing slice " << slice1<<" from row "<< from<< " to " <<to-1<<endl;
for (i = from; i < to; i++)
{
for (j = 0; j < D; j++)
{
C[i][j] = 0;
for ( k = 0; k < D; k++)
C[i][j] += A[i][k]*B[k][j];
}
}
cout<<" finished slice "<<slice1<<endl;
return NULL;
}
main.c:
extern "C"
{
#include <pthread.h>
#include <unistd.h>
}
#include <iostream>
#include "matmul.h"
using namespace std;
// Size by SIZE matrices
// number of threads
matThread* parm=NULL;
int main(int argc, char* argv[])
{
pthread_t* thread; // pointer to a group of threads
int i;
if (argc!=2)
{
cout<<"Usage:"<< argv[0]<<" number_of_threads"<<endl;
exit(-1);
}
num_thrd = atoi(argv[1]);
init_matrix(A);
init_matrix(B);
thread = (pthread_t*) malloc(num_thrd*sizeof(pthread_t));
matThread *parm = new matThread();
for (i = 0; i < num_thrd; i++)
{
parm->slice=i;
// creates each thread working on its own slice of i
if (pthread_create (&thread[i], NULL, multiply, (void*)parm) != 0)
{
cerr<<"Can't create thread"<<endl;
free(thread);
exit(-1);
}
}
for (i = 1; i < num_thrd; i++)
pthread_join (thread[i], NULL);
cout<<"\n\n";
print_matrix(A);
cout<<"\n\n\t *"<<endl;
print_matrix(B);
cout<<"\n\n\t="<<endl;
print_matrix(C);
cout<<"\n\n";
free(thread);
return 0;
}
The commands that I use are:
g++ -c -Wall -fPIC matmul.cpp -o matmul.o and
g++ -shared -o libMatmul.so matmul.o
The code might look little off because I am passing SIZE(dim) in a struct when its already in #define, but this is how I want it to be implemented. Its a test program for a bigger project that I am doing.
Any help is greatly appreciated! Thanks in advance.
First, you're mixing a lot of C and C++ idioms (calling free and new for instance) and you're not using any C++ library/STL features (like a std::vector or std::list instead of a C array), so while your code is 'technically' valid (minus some bugs) it's not good practice to mix C and C++ like that, there are many small idiosyncratic differences between C and C++ (syntax, compilation and linkage differences for example) that can add confusion to the code if it's not explicitly clear to the intentions.
That being said, I've made some changes to your code to make it C++98 compatible (and fix the bugs):
start matmul.h:
#ifndef matmul_h__
#define matmul_h__
#define SIZE 10
#include <pthread.h>
typedef struct matThread {
int slice;
int dim;
pthread_t handle;
matThread() : slice(0), dim(0), handle(0) {}
matThread(int s) : slice(s), dim(0), handle(0) {}
matThread(int s, int d) : slice(s), dim(d), handle(0) {}
} matThread;
// explicitly define as extern (for clarity)
extern int num_thrd;
extern int A[SIZE][SIZE];
extern int B[SIZE][SIZE];
extern int C[SIZE][SIZE];
extern void init_matrix(int m[][SIZE]);
extern void print_matrix(int m[][SIZE]);
extern void* multiply(void* matThread);
#endif
start matmul.cpp:
#include <iostream> // <stdio.h>
#include "matmul.h"
int num_thrd = 1;
int A[SIZE][SIZE];
int B[SIZE][SIZE];
int C[SIZE][SIZE];
// initialize a matrix
void init_matrix(int m[][SIZE])
{
int i, j, val;
for (i = 0, val = -1; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
m[i][j] = ++val;
}
}
}
void print_matrix(int m[][SIZE])
{
int i, j;
for (i = 0; i < SIZE; i++) {
std::cout << "\n\t|"; // printf
for (j = 0; j < SIZE; j++) {
std::cout << m[i][j];
}
std::cout << "|"; // printf
}
}
// thread function: taking "slice" as its argument
void* multiply(void* param)
{
matThread* s = (matThread*)param; // retrive the slice info
int slice1 = s->slice;
int D = s->dim = 10;
int from = (slice1 * D) / num_thrd; // note that this 'slicing' works fine
int to = ((slice1+1) * D) / num_thrd; // even if SIZE is not divisible by num_thrd
int i, j, k;
std::cout << "computing slice " << slice1 << " from row " << from << " to " << (to-1) << std::endl; // printf
for (i = from; i < to; i++) {
for (j = 0; j < D; j++) {
C[i][j] = 0;
for ( k = 0; k < D; k++) {
C[i][j] += A[i][k]*B[k][j];
}
}
}
std::cout << " finished slice " << slice1 << std::endl; // printf
return NULL;
}
start main.cpp:
#include <iostream>
#include <cstdlib> // atoi .. if C++11, you could use std::stoi in <string>
#include "matmul.h"
int main(int argc, char** argv)
{
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " number_of_threads" << std::endl;
return -1;
} else {
num_thrd = std::atoi(argv[1]);
}
matThread mt[num_thrd];
int i = 0;
init_matrix(A);
init_matrix(B);
for (i = 0; i < num_thrd; i++) {
mt[i].slice = i;
// creates each thread working on its own slice of i
if (pthread_create(&mt[i].handle, NULL, &multiply, static_cast<void*>(&mt[i])) != 0) {
printf("Can't create thread\n");
return -1;
}
}
for (i = 0; i < num_thrd; i++) {
pthread_join(mt[i].handle, NULL);
}
std::cout << "\n\n";
print_matrix(A);
std::cout << "\n\n\t *\n";
print_matrix(B);
std::cout << "\n\n\t=\n";
print_matrix(C);
std::cout << "\n\n";
return 0;
}
To compile and use it you'll need to do the following commands:
g++ -c -Wall -fPIC matmul.cpp -o matmul.o
g++ -shared -Wl,-soname,libMatmul.so -o libMatmul.so.1 matmul.o
ln /full/path/to/libMatmul.so.1 /usr/lib/libMatmul.so
g++ main.cpp -o matmul -Wall -L. -lMatmul -pthread
Note that for your system to be able to find and link against the shared library you've just created, you'll need to ensure it's in your distro's lib folder (like /usr/lib/). You can copy/move it over, create a link to it (or a sym link via ln -s if you can't do hard links), and if you don't want to copy/move/link it, you can also ensure your LD_LIBRARY_PATH is properly set to include the build directory.
As I said; your code is NOT inherently C++ aside from the few print statements (std::cout, etc), and changing the C++ code (std::cout to printf and some other minor things for example) you could compile this as standard C99 code. I'm not 100% sure how the rest of your shared library will be designed so I didn't change the structure of the lib code (i.e. the functions you have) but if you wanted this code to be 'more C++' (i.e. with classes/namespaces, STL, etc.), you'd basically need to redesign your code, but given the context of your code, I don't think that's absolutely necessary unless you have a specific need for it.
I hope that can help.
Should
for (i = 1; i < num_thrd; i++)
not be
for (i = 0; i < num_thrd; i++)
You created num_thrd threads, but did not join all of them, therefore, a race condition is created as you're trying to read the data before the thread is finished.
I have modified the code from my previous question, and now it looks like this:
//#include "stdafx.h"
#include <iostream>
#include <cstring>
#include <chrono>
#include <cassert>
using namespace std;
const int MAX_SIZE=10000;
const int MAX_STRINGS = 10;
char** strings=new char*[10];
int len;
char* GetLongestCommonSubstring( char* str1, char* str2 );
inline void readNumberSubstrings();
inline const char* getMaxSubstring();
void readNumberSubstrings()
{
cin >> len;
assert(len >= 1 && len <=MAX_STRINGS);
for(int i=0; i<len;i++)
strings[i]=new char[MAX_SIZE];
for(int i=0; i<len; i++)
cin >> strings[i];
}
const char* getMaxSubstring()
{
char *maxSubstring=strings[0];
auto begin = chrono::high_resolution_clock::now();
for(int i=1; i < len; i++)
maxSubstring=GetLongestCommonSubstring(maxSubstring, strings[i]);
cout << chrono::duration_cast <chrono::milliseconds> (chrono::high_resolution_clock::now()-begin).count() << endl;
return maxSubstring;
}
char* GetLongestCommonSubstring( char* string1, char* string2 )
{
if (strlen(string1)==0 || strlen(string2)==0) cerr << "error!";
int *x=new int[strlen(string2)+ 1]();
int *y= new int[strlen(string2)+ 1]();
int **previous = &x;
int **current = &y;
int max_length = 0;
int result_index = 0;
int length;
int M=strlen(string2) - 1;
for(int i = strlen(string1) - 1; i >= 0; i--)
{
for(int j = M; j >= 0; j--)
{
if(string1[i] != string2[j])
(*current)[j] = 0;
else
{
length = 1 + (*previous)[j + 1];
if (length > max_length)
{
max_length = length;
result_index = i;
}
(*current)[j] = length;
}
}
swap(previous, current);
}
delete[] x;
delete[] y;
string1[max_length+result_index]='\0';
return &(string1[result_index]);
}
int main()
{
readNumberSubstrings();
cout << getMaxSubstring() << endl;
return 0;
}
It's still solving the generalised longest common substring problem, and now it's rather fast.
But there's a catch: if a user specifies, say, 3 as a number of strings he's about to enter, and then only actually enters one string, this code waits forever.
How do I change that?
If you read from a file and the number of arguments isn't equal to the number of arguments provided, just print a nice, clean error message to the user.
"Expected 7 arguments, received 3:"
Print out the arguments you found so the user has an idea of what the program is looking at when it spits out the error.
As for human input, I agree with the comments. The program should wait until the user close it or enters all the needed arguments.