Segmentation fault when I call operator new in linux mint - c++

On Linux Mint, I use operator new to alloc memory:
int maxNummber = 1000000;
int* arr = new int[maxNumber];
when I run my code, I meet
flybird#flybird ~/cplusplus_study $ ./a.out
-412179
Segmentation fault
when I change maxNumber = 100, the code runs successfully.
the result of command free -m:
flybird#flybird ~/cplusplus_study $ free -m
total used free shared buffers cached
Mem: 2016 800 1216 0 158 359
-/+ buffers/cache: 283 1733
Swap: 2045 0 2045
This is the actual code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <ctime>
#include <memory>
#include <string.h>
#include <iterator>
#include <cstdlib>
using namespace std;
class GenRandomNumber;
class BitMap
{
public:
BitMap(int n):maxNumer(n)
{
int length = 1 + n / BITSPERWORD;
pData = new int[length];
memset(pData, 0, length);
}
void set(int i)
{
pData[i>>SHIFT] |= 1<<(i & MASK); // i&MASK 相当于i%32
}
void clear(int i)
{
pData[i>>SHIFT] &= ~(1<<(i & MASK)); // i>>SHIFT 相当于 i/32
}
bool test(int i)
{
return pData[i>>SHIFT] & (1<<(i & MASK));
}
void sort(string inputFile, string outputFile)
{
ifstream read(inputFile.c_str());
ofstream write(outputFile.c_str());
int temp = 0;
while (read>>temp)
set(temp);
for (int i = 0; i < maxNumer; ++i)
{
if(test(i))
write<<i<<endl;
}
read.close();
write.close();
}
~BitMap()
{
delete []pData;
pData = NULL;
}
private:
int* pData;
int maxNumer;
enum{ SHIFT = 5, MASK = 0x1F, BITSPERWORD = 32};
};
class GenRandomNumber
{
public:
static GenRandomNumber* genInstance()
{
if(!mInstance.get())
mInstance.reset(new GenRandomNumber());
return mInstance.get();
}
void generate1(string fileName, int m, int maxNumber)
{
ofstream outFile(fileName.c_str());
int* arr = new int[maxNumber];
for(int i = 0; i < maxNumber; i++)
arr[i] = i;
int temp = 0;
for(int j = 0; j < m; j++)
{
temp = randomRange(j, maxNumber - 1);
cout<<temp<<endl;
swap(arr[j], arr[temp]);
}
copy(arr, arr + m, ostream_iterator<int>(outFile, "\n"));
delete []arr;
outFile.close();
}
void generate2(string fileName, int m, int maxNumber)
{
BitMap bitmap(maxNumber);
ofstream outFile(fileName.c_str());
int count = 0;
int temp;
while (count < m)
{
srand(time(NULL));
temp = randomRange(0, maxNumber);
cout<<temp<<endl;
if (!bitmap.test(temp))
{
bitmap.set(temp);
outFile<<temp<<endl;
count++;
}
}
outFile.close();
}
private:
GenRandomNumber(){};
GenRandomNumber(const GenRandomNumber&);
GenRandomNumber& operator=(const GenRandomNumber&);
int randomRange(int low, int high)
{
srand(clock()); // better than srand(time(NULL))
return low + (RAND_MAX * rand() + rand()) % (high + 1 - low);;
}
static auto_ptr<GenRandomNumber> mInstance;
};
auto_ptr<GenRandomNumber> GenRandomNumber::mInstance;
int main()
{
const int MAX_NUMBER = 1000000;
GenRandomNumber *pGen = GenRandomNumber::genInstance();
pGen->generate1("test.txt", MAX_NUMBER, MAX_NUMBER);
BitMap bitmap(MAX_NUMBER);
bitmap.sort("test.txt", "sort.txt");
return 0;
}

gdb already gave you a hint where the error is coming from. The only place where you use swap is in this function:
void generate1(string fileName, int m, int maxNumber)
{
ofstream outFile(fileName);
int* arr = new int[maxNumber];
for(int i = 0; i < maxNumber; i++)
arr[i] = i;
int temp = 0;
for(int j = 0; j < m; j++)
{
temp = randomRange(j, maxNumber - 1);
cout<<temp<<endl;
swap(arr[j], arr[temp]); // <----
}
copy(arr, arr + m, ostream_iterator<int>(outFile, "\n"));
delete []arr;
outFile.close();
}
Swapping two ints isn't likely to be the culprit, unless you give it invalid input to begin with. arr[j] is pretty straightforward and should be fine, but what about arr[temp]? temp is calculated here:
temp = randomRange(j, maxNumber - 1);
and randomRange function looks like this:
int randomRange(int low, int high)
{
srand(clock()); // better than srand(time(NULL))
return low + (RAND_MAX * rand() + rand()) % (high + 1 - low);;
}
I'd say this is your problem. RAND_MAX * rand() probably overflows and gives you big negative numbers. Hopefully it's obvious why that's not good.

1,000,000 probably should not fail on a modern desktop, so I expect you are blowing up elsewhere.
To see what/where the problem is:
$ gdb
gdb> file ./a.out
gdb> run
<wait for crash>
gdb> bt full
If the allocation failed, you should see an uncaught bad_alloc exception.
Otherwise, please post the source code and results of the backtrace.

The problem is in your randomRange function.
return low + (RAND_MAX * rand() + rand()) % (high + 1 - low);;
I don't know, why do you multiple (RAND_MAX + 1) by rand()(which return value between 0 and RAND_MAX), but it causes overflow and may be negative.
If C++11 is an option for you, I can suggest use uniform_int_distribution. It will return a number between passed min and max values.
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 6);
for (int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}

Here's one of the problems. m is too large and exceeds maxNumber. arr[j], when j=m, exceeds the its bounds because arr is only maxNumber in size. See the info on stack frame #1: m=1606416912, maxNumber=999999.
By the way, a well placed assert would have alerted you to this problem (I'm a big fan of self debugging code - I hate spending time under the debugger):
void generate1(string fileName, int m, int maxNumber)
{
assert(!fileName.empty());
assert(m > 0 && maxNumber > 0);
assert(m <= maxNumber);
...
}
And the back trace:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000010007eef8
std::swap<int> (__a=#0x100200000, __b=#0x10007eef8) at stl_algobase.h:99
99 __a = __b;
(gdb) bt full
#0 std::swap<int> (__a=#0x100200000, __b=#0x10007eef8) at stl_algobase.h:99
__tmp = 0
#1 0x0000000100000ff1 in GenRandomNumber::generate1 (this=0x7fff5fbffa10, fileName=#0x100200000, m=1606416912, maxNumber=999999) at t.cpp:91
outFile = {
<std::basic_ostream<char,std::char_traits<char> >> = {
<std::basic_ios<char,std::char_traits<char> >> = {
<std::ios_base> = {
_vptr$ios_base = 0x7fff745bc350,
_M_precision = 6,
_M_width = 0,
_M_flags = 4098,
_M_exception = std::_S_goodbit,
_M_streambuf_state = std::_S_goodbit,
_M_callbacks = 0x0,
_M_word_zero = {
_M_pword = 0x0,
_M_iword = 0
},
_M_local_word = {{
_M_pword = 0x0,
_M_iword = 0
}, {
_M_pword = 0x0,
_M_iword = 0
}, {
_M_pword = 0x0,
_M_iword = 0
}, {
_M_pword = 0x0,
_M_iword = 0
}, {
_M_pword = 0x0,
_M_iword = 0
}, {
_M_pword = 0x0,
_M_iword = 0
}, {
_M_pword = 0x0,
_M_iword = 0
}, {
_M_pword = 0x0,
_M_iword = 0
}},
_M_word_size = 8,
_M_word = 0x7fff5fbff910,
_M_ios_locale = {
_M_impl = 0x7fff745c1880
}
},
members of std::basic_ios<char,std::char_traits<char> >:
_M_tie = 0x0,
_M_fill = 0 '\0',
_M_fill_init = false,
_M_streambuf = 0x7fff5fbff660,
_M_ctype = 0x7fff745c1ab0,
_M_num_put = 0x7fff745c1dd0,
_M_num_get = 0x7fff745c1dc0
},
members of std::basic_ostream<char,std::char_traits<char> >:
_vptr$basic_ostream = 0x7fff745bc328
},
members of std::basic_ofstream<char,std::char_traits<char> >:
_M_filebuf = {
<std::basic_streambuf<char,std::char_traits<char> >> = {
_vptr$basic_streambuf = 0x7fff745bc230,
_M_in_beg = 0x100803200 "",
_M_in_cur = 0x100803200 "",
_M_in_end = 0x100803200 "",
_M_out_beg = 0x0,
_M_out_cur = 0x0,
_M_out_end = 0x0,
_M_buf_locale = {
_M_impl = 0x7fff745c1880
}
},
members of std::basic_filebuf<char,std::char_traits<char> >:
_M_lock = {
__sig = 0,
__opaque = '\0' <repeats 55 times>
},
_M_file = {
_M_cfile = 0x7fff756bf0a0,
_M_cfile_created = true
},
_M_mode = 48,
_M_state_beg = {
__mbstate8 = '\0' <repeats 127 times>,
_mbstateL = 0
},
_M_state_cur = {
__mbstate8 = '\0' <repeats 127 times>,
_mbstateL = 0
},
_M_state_last = {
__mbstate8 = '\0' <repeats 127 times>,
_mbstateL = 0
},
_M_buf = 0x100803200 "",
_M_buf_size = 1024,
_M_buf_allocated = true,
_M_reading = false,
_M_writing = false,
_M_pback = 0 '\0',
_M_pback_cur_save = 0x0,
_M_pback_end_save = 0x0,
_M_pback_init = false,
_M_codecvt = 0x7fff745c1cf0,
_M_ext_buf = 0x0,
_M_ext_buf_size = 0,
_M_ext_next = 0x0,
_M_ext_end = 0x0
}
}
#2 0x0000000100000a18 in main () at t.cpp:140
bitmap = {
pData = 0x7fff5fc005a8,
maxNumer = 17
}
pGen = (GenRandomNumber *) 0x1001000e0

There is one problem in the code may not directly explain the segment fault, but should also draw your attention. Note that In the class BitMap, the constructor:
BitMap(int n):maxNumer(n)
{
int length = 1 + n / BITSPERWORD;
pData = new int[length];
memset(pData, 0, length);
}
The third parameter of memset is meant to be the size of allocated array, not number of elements, so it should be:
BitMap(int n):maxNumer(n)
{
int length = 1 + n / BITSPERWORD;
pData = new int[length];
memset(pData, 0, length * sizeof(int));
}
The original code might causes problem because only part of the allocated array is initialized to zero by memset. The remaining code might be logically wrong because class BitMap do binary operator in the member function (set, clear, test), in which all of them presume all elements of the array that pData pointed to are set to be zero.

Related

What is corrupting the stack of this multidimensional array?

This script produces a fibonacci spiral which starts off in the centre and branches outward. Although the output is correct, i get an error message saying:
"Run-Time Check Failure #2 - Stack around the variable 'fibArr' was corrupted."
I've tried reducing fibCount by 1, but this caused the central number to be 0 which I dont want.
int fibFunc(int);
int main() {
//--setting variables
const int rowCount = 5, colCount = 5;
const int fibCount = rowCount * colCount - 1;
static int f;
int i, j;
//--creating grid
int grid[rowCount][colCount] = { 0 };
//Create fibArr
f = fibCount;
int fibArr[fibCount];
while (f >= 0) {
fibArr[f] = fibFunc(f);
f--;
}
//directions settings
enum direction {
DOWN, RIGHT, UP, LEFT
} d = DOWN;
//spiral loop
int R = 0, C = 0; //R for row, C for column
f = fibCount;
while (f >= 0) {
grid[R][C] = fibArr[f];
f--;
if (d == DOWN) {
if (grid[R+1][C] == 0)
R++;
else d = RIGHT;
}
if (d == RIGHT) {
if (grid[R][C+1] == 0)
C++;
else d = UP;
}
if (d == UP) {
if (grid[R-1][C] == 0)
R--;
else d = LEFT;
}
if (d == LEFT) {
if (grid[R][C-1] == 0)
C--;
else {
d = DOWN;
R++;
}
}
}
printFib(fibArr, fibCount);
for (i = 0; i < rowCount; i++) {
for (j = 0; j < colCount; j++) {
cout << setw(7) << grid[i][j];
}
cout << endl;
cout << endl;
}
system("pause>nul");
}
int fibFunc(int n) {
if (n == 0 || n == 1)
return 1;
else
return fibFunc(n - 1) + fibFunc(n - 2);
}
Output
75025 55 89 144 233
46368 34 1 2 377
28657 21 1 3 610
17711 13 8 5 987
10946 6765 4181 2584 1597
As juanchopanza pointed out, array indexing is from 0 to size - 1.
const int rowCount = 5, colCount = 5;
const int fibCount = rowCount * colCount - 1;
This would result in:
fibCount = 24 = ( 5 * 5 ) - 1;
Further down, at your while loop:
int R = 0, C = 0; //R for row, C for column
f = fibCount;
while (f >= 0) {
grid[R][C] = fibArr[f]; // f = 24; size = 24;
...
}
Here you take a value from your array fibArray with the index of 24. Last index would be 23.
Change this to:
const int fibCount = rowCount * colCount;
Then before your while loop:
f = fibCount - 1;
Besides that I would use a single dimensional array like this:
int rows = 5, cols = 5;
char* tst = new char[ rows * cols ];
int select_row = 2;
int select_col = 3;
tst[ select_row * cols + select_col ] = 65;
char c = tst[ select_row * cols + select_col ];
delete[] tst;

C++ Not Counting white beands

I need some help. I'm writing a code in C++ that will ultimately take a random string passed in, and it will do a break at every point in the string, and it will count the number of colors to the right and left of the break (r, b, and w). Here's the catch, the w can be either r or b when it breaks or when the strong passes it ultimately making it a hybrid. My problem is when the break is implemented and there is a w immediately to the left or right I can't get the program to go find the fist b or r. Can anyone help me?
#include <stdio.h>
#include "P2Library.h"
void doubleNecklace(char neck[], char doubleNeck[], int size);
int findMaxBeads(char neck2[], int size);
#define SIZE 7
void main(void)
{
char necklace[SIZE];
char necklace2[2 * SIZE];
int brk;
int maxBeads;
int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0;
char leftColor, rightColor;
initNecklace(necklace, SIZE);
doubleNecklace(necklace, necklace2, SIZE);
maxBeads = findMaxBeads(necklace2, SIZE * 2);
checkAnswer(necklace, SIZE, maxBeads);
printf("The max number of beads is %d\n", maxBeads);
}
int findMaxBeads(char neck2[], int size)
{
int brk;
int maxBeads;
int leftI, rightI, leftCount = 0, rightCount=0, totalCount, maxCount = 0;
char leftColor, rightColor;
for(brk = 0; brk < 2 * SIZE - 1; brk++)
{
leftCount = rightCount = 0;
rightI = brk;
rightColor = neck2[rightI];
if(rightI == 'w')
{
while(rightI == 'w')
{
rightI++;
}
rightColor = neck2[rightI];
}
rightI = brk;
while(neck2[rightI] == rightColor || neck2[rightI] == 'w')
{
rightCount++;
rightI++;
}
if(brk > 0)
{
leftI = brk - 1;
leftColor = neck2[leftI];
if(leftI == 'w')
{
while(leftI == 'w')
{
leftI--;
}
leftColor = neck2[leftI];
}
leftI = brk - 1;
while(leftI >= 0 && neck2[leftI] == leftColor || neck2[leftI] == 'w')
{
leftCount++;
leftI--;
}
}
totalCount = leftCount + rightCount;
if(totalCount > maxCount)
{
maxCount = totalCount;
}
}
return maxCount;
}
void doubleNecklace(char neck[], char doubleNeck[], int size)
{
int i;
for(i = 0; i < size; i++)
{
doubleNeck[i] = neck[i];
doubleNeck[i+size] = neck[i];
}
}
I didn't study the code in detail, but something is not symmetric: in the for loop, the "left" code has an if but the "right" code doesn't. Maybe you should remove that -1 in the for condition and add it as an if for the "right" code:
for(brk = 0; brk < 2 * SIZE; brk++)
{
leftCount = rightCount = 0;
if (brk < 2 * SIZE - 1)
{
rightI = brk;
rightColor = neck2[rightI];
//...
}
if(brk > 0)
{
leftI = brk - 1;
leftColor = neck2[leftI];
//...
}
//...
Just guessing, though... :-/
Maybe you should even change those < for <=.

c++ unsigned char memory copy

I need to pass an unsigned char array from one method to another, and i tried using this code:
{
unsigned char *lpBuffer = new unsigned char[182];
ReceiveSystemState(lpBuffer);
}
BOOL ReceiveSystemState(unsigned char *lpBuffer)
{
unsigned char strRecvBuffer[182] = { 0 };
//strRecvBuffer construction
memcpy(lpBuffer, strRecvBuffer, sizeof(strRecvBuffer));
return TRUE;
}
Neither of those 3 methods (used in ReceiveSystemState) worked as i expected. After using each one of them all that it is copied is the first char from strRecvBuffer and nothing more. The strRecvBuffer has empty chars from element to element, but i need those as they are, because that string is a message from a hardware device and that message will be anallysed using a protocol. What do i miss here? Do i initialize lpBuffer wrong?
EDIT: I've used a simple memcpy method to do the job. Still the same result: all that it is copied is the first char of strRecvBuffer.
EDIT2: Working code:
{
unsigned char *lpBuffer = new unsigned char[182];
ReceiveSystemState(lpBuffer);
for (int i = 0; i < 144; i++)
{
memcpy(&c_dateKG[i], lpBuffer + i * sizeof(unsigned char), sizeof(unsigned char) );
}
}
BOOL ReceiveSystemState(unsigned char *lpBuffer)
{
unsigned char strRecvBuffer[182] = { 0 };
//strRecvBuffer construction
memcpy(lpBuffer, strRecvBuffer, sizeof(strRecvBuffer));
return TRUE;
}
Your code is absolutely garbage. Some notes:
Use sizeof:
Use sizeof(static_massive_name); or count_of_arr_elements * sizeof(arr_type);
For example:
unsigned char src[255];
unsigned char dst[255];
// fill src with random data
for (int i = 0; i < 255; ++i) {
src[i] = static_cast<unsigned char> (rand() % 255);
}
memcpy(dst, src, sizeof(dst));
// now dst will have copied values from src (random numbers)
UPDATE:
Full source code for testing:
#include <iostream>
#include <string.h>
#include <time.h>
#include <stdlib.h>
using namespace std;
void print(unsigned char* arr, size_t size) {
for (size_t i = 0; i < size; ++i) {
// see type casting (to int)!!!
cout << "arr[" << i << "] = " << (int)arr[i]<< endl;
}
}
int main() {
srand(time(0));
// unsigned char type hold values from 0 to 255
unsigned char src[15];
unsigned char dst[15];
for (int i = 0; i < 15; ++i) {
src[i] = rand() % 255;
}
memcpy(dst, src, sizeof(dst));
print(src, 15);
print(dst, 15);
return 0;
}
Result:
arr[0] = 34
arr[1] = 80
arr[2] = 183
arr[3] = 112
arr[4] = 18
arr[5] = 120
arr[6] = 183
arr[7] = 0
arr[8] = 0
arr[9] = 0
arr[10] = 0
arr[11] = 57
arr[12] = 137
arr[13] = 4
arr[14] = 8
arr[0] = 34
arr[1] = 80
arr[2] = 183
arr[3] = 112
arr[4] = 18
arr[5] = 120
arr[6] = 183
arr[7] = 0
arr[8] = 0
arr[9] = 0
arr[10] = 0
arr[11] = 57
arr[12] = 137
arr[13] = 4
arr[14] = 8

Passing array to function in C++ changes it's value without me performing any change inside the function

I'm having a very weird problem with a C++ array. Everything is well with it until I pass it to a function to write it onto disk, after that, the array is changed without me performing any operation of it.
int saveMatrix(Long64_t*, unsigned int, const char*);
void resetArray(Long64_t* array, unsigned int size)
{
for (unsigned long int i = 0; i < size; i++)
array[i] = 0;
}
int saveMatrix(Long64_t* array, unsigned int size, const char* filename)
{
// Returns:
// 0 - Exit
// 1 - Error
ofstream out(filename, ios::out);
if (!out) {
cout << "Cannot open file.";
return 1;
}
for (unsigned long int i = 0; i < size; i++) {
out << array[i] << " ";
}
out.close();
return 0;
}
int main(int argc, char** argv) {
if (argc != 2) {
cout << "The program needs the name of the ROOT file to analyse." << endl;
return 1;
}
else
return gf_partial(argv[1]);
}
#endif
#include "../include/ROOT_Tree.hh"
#include "jbmArray.hh"
int gf_partial(const char* name) {
// init macro
gROOT->Reset();
unsigned long int i, j;
const unsigned int DetectorNumber = 4;
/* Detectors are:
0 lefs60Foil
1 lefs60Fl
2 lefs60Ml
3 lefs150Foil
4 lefs150F
5 lefs150M
6 ca60D
7 ca60C
8 ca60B
*/
const double sourceRadius = 20.; // LAN2B In cm
// const double sourceRadius = 11.; // LAN2A In cm
const Int_t numberOfChannels = 4;
// Float_t energyChannels[numberOfChannels] = {52., 85., 141., 227.}; // LAN2A F electron
Float_t energyChannels[numberOfChannels] = {51., 80., 135., 218.}; // LAN2B F electron
// Float_t energyChannels[numberOfChannels] = {42., 55., 130., 220.}; // LAN2B B electron
// Float_t energyChannels[numberOfChannels] = {66., 101., 167., 269., 447., 798., 1391., 2926.}; // LAN2B M proton
const Int_t numberOfDetectors = 9;
Float_t energyChannelsError[numberOfChannels] = {0., 0., 0., 0.};
// Float_t energyChannelsError[numberOfChannels] = {0., 0., 0., 0., 0., 0., 0., 0.};
Float_t vGeometryFactors[numberOfChannels];
Float_t vError[numberOfChannels]; // the error amount
Float_t vRealError[numberOfChannels]; // the calculated error
Long64_t nHitsInDetector[numberOfChannels];
resetArray(nHitsInDetector, numberOfChannels);
Long64_t nHitsInDetectorNoSecondaries[numberOfChannels];
resetArray(nHitsInDetectorNoSecondaries, numberOfChannels);
double nEmitedParticlesPerChannel[numberOfChannels];
resetArray(nEmitedParticlesPerChannel, numberOfChannels);
//exclusiongraph()->Update();
if (!TClassTable::GetDict("Event")) {
gSystem->Load("../lib/libROOT_Tree.so");
}
// read the tree file generated in GEANT4
TFile* treeFile = new TFile(name);
treeFile->ls();
TTree *myTree = (TTree*) treeFile->Get("hiscaleSim");
// Create pointer to an event object for reading the branch values.
Event* myEvent = new Event();
TBranch* bEvent = myTree->GetBranch("EventBranch");
bEvent->SetAddress(&myEvent);
TClonesArray* hits = myEvent->GetHits();
Hit* myHit;
unsigned long int nEvents = myTree->GetEntries();
cout << endl << "Number of Total Events = " << nEvents << endl << endl;
Float_t sourceEnergy = 0.0;
Float_t depositedEnergy = 0.0;
Float_t sourceTime = 0.0;
UInt_t parentID = 0;
UInt_t trackID = 0;
std::vector<float> fSourcePosition(3);
std::vector<float> minSourcePosition(3);
std::vector<float> maxSourcePosition(3);
std::vector<float> fSourceMomentumDirection(3);
std::vector<float> minSourceMomentumDirection(3);
std::vector<float> maxSourceMomentumDirection(3);
std::vector<float> totalDepositedEnergy(numberOfDetectors);
//std::vector<unsigned long int> nHitsInDetector(numberOfDetectors);
// std::vector<unsigned long int> nHitsInDetectorNoSecondaries(numberOfChannels);
Float_t fParticlePDGMass = 0.0;
Float_t fParticlePDGCharge = 0.0;
//fParticleAtomicNumber = 0;
//fParticleAtomicMass = 0;
for (i = 0; i < nEvents; i++) {
myTree->GetEntry(i);
depositedEnergy = 0;
sourceEnergy = myEvent->GetSourceEnergy();
for (j = 0; j < myEvent->GetNHit(); j++) {
myHit = (Hit*)hits->UncheckedAt(j);
if (myHit->GetDetectorN() == DetectorNumber)
depositedEnergy = myHit->GetTotalDepositedEnergy();
}
parentID = myEvent->GetParentID();
trackID = myEvent->GetTrackID();
for (j = 0; j < numberOfChannels; j++) {
if (sourceEnergy == energyChannels[j]) {
nEmitedParticlesPerChannel[j]++;
if (depositedEnergy != 0) {
if (parentID == 0)
nHitsInDetectorNoSecondaries[j]++;
nHitsInDetector[j]++;
}
}
}
}
char strnHitsInDetector[80];
strcpy (strnHitsInDetector, name);
strcat (strnHitsInDetector, ".nHitsInDetector");
saveMatrix(nHitsInDetector, numberOfChannels, strnHitsInDetector);
//char strnHitsInDetector[80];
strcpy (strnHitsInDetector, name);
strcat (strnHitsInDetector, ".nHitsInDetectorNoSecondaries");
saveMatrix(nHitsInDetectorNoSecondaries, numberOfChannels, strnHitsInDetector);
char strnEmitedParticlesPerChannel[80];
strcpy (strnEmitedParticlesPerChannel, name);
strcat (strnEmitedParticlesPerChannel, ".nEmitedParticlesPerChannel");
saveMatrix(nEmitedParticlesPerChannel, numberOfChannels, strnEmitedParticlesPerChannel);
// from now on nEmitedParticlesPerChannel changes it's value and it's not ok anymore.
I think the issue is in these lines of code:
const Int_t numberOfChannels = 2;
Long64_t nEmitedParticlesPerChannel[numberOfChannels];
resetArray(nEmitedParticlesPerChannel, numberOfChannels);
nEmitedParticlesPerChannel[1] = 10;
nEmitedParticlesPerChannel[2] = 20;
Notice that you've sized the array nEmittedParticlesPerChannel to have two elements in it, but then write to indices 1 and 2. Since C++ arrays are zero-indexed, this means that you are writing off the end of the array and clobbering whatever values in memory happen to be right after it. This might destroy the contents of the array you passed in as a parameter, since this results in undefined behavior.
To fix this, try rewriting the last two lines as
nEmitedParticlesPerChannel[0] = 10;
nEmitedParticlesPerChannel[1] = 20;
Hope this helps!

How to calculate bit transitions using bitset < >

I am new to C++. I want to calculate the no of transitions from 0 to 0, 0 to 1, 1 to 0 and 1 to 1 in a 9 bit sequence. I have written the following code;
int main {
srand((unsigned)time(0));
unsigned int x;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9>bitseq(x);
for(int j=0;j<=bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&(b==0)==0)
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&(b==1)==0)
{
transition0_1 = transition0_1 + 1;
else if ((a==1)&(b==0)==0)
{
transition1_0 = transition1_0 + 1;
else
{
transition1_1 = transition1_1 + 1;
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
}
}
Somebody please guide me on the following
how to save the last bit value in loop-2 to check the transition from last bit of the last bitset output to the 1st bit of the next bitset output?
If this does not work, How I can save it in vector and use iterators to check the transitions?
First of all, the loop index j is running past the end of the bitset. Indices go from 0 to bitseq.size()-1 (inclusive). If you're going to test j and j+1 the largest value j can take is bitseq.size()-2.
Second, the ==0 part that appears in your ifs is strange, you should just use
if( (a==0)&&(b==0) )
Notice the use of two &&. While a single & works for this code, I think it's better to use the operator that correctly conveys your intentions.
And then to answer your question, you can keep a "last bit" variable that is initially set to a sentinel value (indicating you're seeing the first bitseq just now) and compare it to bitseq[0] before the start of loop 2. Here's a modified version of your code that should do what you ask.
int main {
srand((unsigned)time(0));
unsigned int x;
int transition0_0 = 0,
transition0_1 = 0,
transition1_0 = 0,
transition1_1 = 0;
int prev = -1;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9> bitseq(x);
if( prev != -1 ) // don't check this on the first iteration
{
bool cur = bitseq.test(0);
if( !prev && !cur )
++transition0_0;
else if( !prev && cur )
++transition0_1;
else if( prev && !cur )
++transition1_0;
else
++transition1_1;
}
for(int j=0;j+1<bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&&(b==0))
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&&(b==1))
{
transition0_1 = transition0_1 + 1;
}
else if ((a==1)&&(b==0))
{
transition1_0 = transition1_0 + 1;
}
else
{
++transition1_1 = transition1_1 + 1;
}
} // for-2
prev = bitseq.test(bitseq.size()-1); // update prev for the next iteration
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
} // for-1
} // main
Would something like this be better for you? Use an array of 4 ints where [0] = 0->0, [1] = 0->1, [2] = 1->0, [3] = 1->1.
int main {
int nTransition[] = { 0,0,0,0 };
bool a,b;
unsigned int x;
int j;
srand ((unsigned)time(0));
for (int i = 0: i < 512; i++) {
x = rand () % 512;
bitset<9> bitseq(x);
if (i == 0) {
a = bitseq.test (0);
j = 1;
} else
j = 0;
for (; j < bitseq.size (); j++) {
b = bitseq.test(j);
int nPos = (a) ? ((b) ? 3 : 2) : ((b) ? 1 : 0);
nTransition[nPos]++;
a = b;
}
}
}