Why won't this loop load the proper event? - c++

Here is the code I wrote, and it runs fine, but it doesn't seem to actually load the events ... instead, it seems to fill the histograms and the cout with one arbitrary miniscule number.
include "TTree.h"
include "TFile.h"
include "TRandom.h"
include "TTree.h"
include "TCanvas.h"
include "TStyle.h"
include <iostream>
include "TH1.h"
include "TChain.h"
using namespace std;
void readtestsimple(){
TFile *file = TFile::Open("/file/");
TTree* comp_tree = (TTree*)file->Get("_compress_tree");
TChain* compchain = new TChain("_compress_tree");
compchain->Add("/file/");
TH1D *comp = new TH1D("comp","_compression",100,0,0.05);
Double_t _compression, _compressionU, _compressionV, _compressionY, _ch_compression;
Int_t _ch;
comp_tree->SetBranchAddress("_compression",&_compression);
comp_tree->SetBranchAddress("_compressionU",&_compressionU);
comp_tree->SetBranchAddress("_compressionV",&_compressionV);
comp_tree->SetBranchAddress("_compressionY",&_compressionY);
Long64_t nentries = compchain->GetEntries();
Long64_t nb = 0, nbytes = 0 ;
for (Long64_t i=0; i<nentries; i++) {
Long64_t entry = compchain->LoadTree(i);
if (entry <0 ) break;
nb = compchain->GetEntry(i); nbytes += nb;
cout << "entry = " << nb << endl;
cout << "compression = " << _compression << endl;
comp->Fill(_compression);
}
cout << "entries = " << nentries << endl;
}
And the output I get is a long repetition of this:
entry = 36
compression = 1.54768e-316
entry = 36
compression = 1.54768e-316
entry = 36
compression = 1.54768e-316
(and at the end, the correct number of entries).
What do I do to make it read out the correct entry?
Please help!

It looks you don't need to use the comp_tree pointer at all. The compchain pointer should be enough to access the data in the TTree because TChain is a TTree. Therefore, you should be able to "link" the variables to the chain/tree branches as:
compchain->SetBranchAddress("_compression",&_compression);
instead of
comp_tree->SetBranchAddress("_compression",&_compression);

Related

How to use CRT batch technique in Microsoft SEAL 3.1?

Can you please tell me whether SEAL 3.1 supports PolyCRTBuilder class? I am trying to run the following program but failed because the class is not declared in this scope.
/**
Suppose I have two arrays x = [1,2,3,4,5] and xMean = [3,3,3,3,3]. I composed and encrypted the two array using PolyCRTBuilder ( xCiphertext and xMeanCiphertext ) . If I subtract the two ciphertexts ( xCiphertext MINUS xMeanCiphertext ), I should get xResult = [-2, -1, 0, 1, 2] but after the homomorphic subtraction I am getting xResultDecrypted = [40959, 40960, 0 ,1, 2] . I can relate the overflow result to the plain modulus set but is there a work around for this problem. Here is the code:
*/
#include <iostream>
#include "seal/seal.h"
using namespace std;
using namespace seal;
/*
Helper function: Prints the parameters in a SEALContext.
*/
void print_parameters(shared_ptr<SEALContext> context)
{
// Verify parameters
if (!context)
{
throw invalid_argument("context is not set");
}
auto &context_data = *context->context_data();
/*
Which scheme are we using?
*/
string scheme_name;
switch (context_data.parms().scheme())
{
case scheme_type::BFV:scheme_name = "BFV";
break;
case scheme_type::CKKS:scheme_name = "CKKS";
break;
default:
throw invalid_argument("unsupported scheme");
}
cout << "/ Encryption parameters:" << endl;
cout << "| scheme: " << scheme_name << endl;
cout << "| poly_modulus_degree: " << context_data.parms().poly_modulus_degree() << endl;
/*
Print the size of the true (product) coefficient modulus.
*/
cout << "| coeff_modulus size: " << context_data.
total_coeff_modulus_bit_count() << " bits" << endl;
/*
For the BFV scheme print the plain_modulus parameter.
*/
if (context_data.parms().scheme() == scheme_type::BFV)
{
cout << "| plain_modulus: " << context_data.
parms().plain_modulus().value() << endl;
}
cout << "\\ noise_standard_deviation: " << context_data.
parms().noise_standard_deviation() << endl;
cout << endl;
}
int main(){
cout << "\nTotal memory allocated from the current memory pool: "<< (MemoryManager::GetPool().alloc_byte_count() >> 20) << " MB" << endl;
EncryptionParameters parms(scheme_type::BFV);
//EncryptionParameters parms;
parms.set_poly_modulus_degree(4096);
parms.set_coeff_modulus(coeff_modulus_128(4096));
parms.set_plain_modulus(40961); ////Make the coefficient modulus prime>2n to enable CRT batching
auto context = SEALContext::Create(parms);
print_parameters(context);
IntegerEncoder encoder(parms.plain_modulus());
KeyGenerator keygen(context);
PublicKey public_key = keygen.public_key();
SecretKey secret_key = keygen.secret_key();
// SEALContext context(parms);
// KeyGenerator keygen(context);
// auto public_key = keygen.public_key();
// auto secret_key = keygen.secret_key();
Encryptor encryptor(context, public_key);
Evaluator evaluator(context);
Decryptor decryptor(context, secret_key);
PolyCRTBuilder crtbuilder(context);
int slot_count = crtbuilder.slot_count();
int row_size = slot_count / 2;
vector<uint64_t> x_pod_matrix(slot_count, 0);
x_pod_matrix[0] = 1;
x_pod_matrix[1] = 2;
x_pod_matrix[2] = 3;
x_pod_matrix[3] = 4;
x_pod_matrix[4] = 5;
Plaintext x_plain_matrix;
crtbuilder.compose(x_pod_matrix, x_plain_matrix);
Ciphertext x_encrypted_matrix;
encryptor.encrypt(x_plain_matrix, x_encrypted_matrix);
vector<uint64_t> x_mean_pod_matrix(slot_count, 0);
x_mean_pod_matrix[0] = 3;
x_mean_pod_matrix[1] = 3;
x_mean_pod_matrix[2] = 3;
x_mean_pod_matrix[3] = 3;
x_mean_pod_matrix[4] = 3;
Plaintext x_mean_plain_matrix;
crtbuilder.compose(x_mean_pod_matrix, x_mean_plain_matrix);
Ciphertext x_mean_encrypted_matrix;
encryptor.encrypt(x_mean_plain_matrix, x_mean_encrypted_matrix);
evaluator.sub_plain(x_encrypted_matrix, x_mean_encrypted_matrix);
// Decrypt x_encrypted_matrix
Plaintext x_plain_result;
decryptor.decrypt(x_encrypted_matrix, x_plain_result);
vector<uint64_t> pod_result;
crtbuilder.decompose(x_plain_result, pod_result);
for(int i = 0; i < 5; i++) {
std::cout << pod_result[i] << '\n';
}
return 0;
}
PolyCRTBuilder has been renamed to BatchEncoder. Take a look at the src/examples directory in SEAL v3.1 (or native/examples in a newer version) and you'll see plenty of examples.
Kind of related to your question: the coeff_modulus_128 function hasn't existed in SEAL for quite a while; the same functionality is provided by the CoeffModulus::BFVDefault function. With these changes your code might work in SEAL 3.5 even.

Getting results from a third party DLL in C++

I am very new to software programming.I have been working on a C++ project (using Code::Blocks) and trying to get results from a third party DLL written with Visual C++ 2010. So far I am able to load the DLL using LoadLibrary() and get the function address using GetProcAddress(). But I am not sure how I can proceed further to get some meaningful results. Information from the third party DLL manual is not very clear, at least to me. I would be much appreciated, if someone can point me to the right direction, please.
DLL information:
Calcdll.dll exports function StartJob.
StartJob, that accepts three parameters
double aInputData[NINPUTDATA], specifies input data
VARIANT aResData[NRESDATA], contains calculation results
VARIANT aOptions[NOPTIONSDATA], specifies optional flags (for future use)
NINPUTDATA: 100
NRESDATA: 100
NOPTIONSDATA 1
Usage from C++
// Calcdlld.h is located in the installation directory together
// with calcwin.dll and calcwin.lib
#include “calcdlld.h”
void CCalcdllsvrView::OnCalcolo()
{
// TODO: Add your control notification handler code here
VARIANT aRis[NRESDATA];
double aInp[NINPUTDATA];
double aOpt[NOPTIONSDATA];
// Collect data from input mask
GetData(vInp);
// Check for errors
if (!StartJob(aInp, aRis, aOpt))
return;
// Show results
ShowResults(aRis);
}
/*
Link Calcdll.lib together with your files.
Warning: positions 14,15 and 30 of the output array contain BSTR values, so in order to convert them to CString (in
Visual C++) is possible to create an instance of the class CString passing aRis[n].bstrVal to the constructor (see
VARIANT structure declaration):
*/
CString coilDescription (aRis[29].bstrVal);
AfxMessageBox(CString(“Coil type: “) + coilDescription);
//Contents of calcdlld.h
#define NINPUTDATA 100
#define NOPTIONSDATA 1
#define NRESDATA 100
extern "C" BOOL FAR PASCAL EXPORT StartJob(double vInp[NINPUTDATA], VARIANT vRis[NRESDATA], double vOpt[NOPTIONSDATA]);
My code
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
#include <windows.h>
int main() {
double vInp[100];
VARIANT vRis[100];
double vOpt[1];
for (int i = 0; i < 100; i++ ) {
vInp[i] = 0;
}
//vInp[] = ;
vInp[0] = 2;
vInp[1] = 25;
vInp[8] = 1;
vInp[9] = 45;
vInp[14] = 2;
vInp[15] = 48;
vInp[16] = 2;
vInp[17] = 16;
vInp[18] = 11250;
vInp[26] = 45;
vInp[28] = 2.41627;
vInp[40] = 1;
vInp[45] = 1;
vInp[50] = 14;
vInp[51] = 2.2;
vInp[60] = 1;
vInp[61] = 0.11;
vInp[62] = 0.35;
vInp[63] = 203;
vInp[77] = 2;
cout << "vInp" << endl;
for (int i = 0; i < 100; i++ ) {
cout << i << ": " << vInp[i] << endl;
}
cout << "Start!" << endl;
typedef int (__stdcall *f_StartJob)(double vInp[100], VARIANT vRis[100], double vOpt[1]);
HINSTANCE hGetProcIDDLL = LoadLibrary("C:\\......\\calcdll.dll");
if (!hGetProcIDDLL) {
cout << "could not load the dynamic library" << endl;
return EXIT_FAILURE;
} else {
cout << "DLL loaded!" << endl << endl;
}
// resolve function address here
f_StartJob StartJob = (f_StartJob)GetProcAddress(hGetProcIDDLL, "StartJob");
if (!StartJob) {
cout << "could not locate the function" << endl;
return EXIT_FAILURE;
}
cout << "StartJob() returned " << StartJob(vInp, vRis, vOpt) << endl;
cout << vRis << endl;
return EXIT_SUCCESS;
}
Many thanks in advance!

Writing a Hash Table to File and Restoring From File in C++

I am working on an assignment for school using hash tables in a structure program. Part of the assignment is writing a hash table composed of 20 primary buckets and 10 overflow buckets, each with 3 slots composed of a key and data field to disk and then restoring from it. Here is what I have so far:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <string.h> // for strcpy()
using namespace std;
typedef char STR10[10+1];
typedef char STR20[20+1];
struct SLOT
{
STR10 key;
STR20 data;
};
struct BUCKET
{
SLOT entry[3];
int count;
BUCKET* overflow;
};
struct HASHTABLE
{
BUCKET pBkt[20];
BUCKET oBkt[10];
};
void WriteHTtoDisk (HASHTABLE ht, char *HashDisk);
void ReportHT (HASHTABLE ht, char * when);
int main()
{
int maxP = 20;
int maxO = 10;
int maxS = 3;
HASHTABLE ht;
STR10 mKey;
STR20 mData;
FILE * inFile;
inFile = fopen("DATAIN.dat","rb");
if (inFile == NULL)
{
cout << " DATAIN file access error ... \n";
cout << " Terminating application ... \n ";
cout << " Press any key ... \n ";
return -100;
}
char crLF;
while (!feof(inFile))
{
fscanf(inFile,"%10c%20c\n",mKey,mData);
mKey[10] = mData[20] = 0; // add string terminators
printf(" MyKey: %10s\n MyData: %20s\n",mKey,mData);
cin.ignore(80,'\n'), cin.get();
//InsertIntoHT (ht, mKey, mData);
}
fclose(inFile);
WriteHTtoDisk(ht, "hashTable.dat");
ReportHT (ht,"BEFORE");
return 0;
}
void WriteHTtoDisk (HASHTABLE ht, char *HashDisk)
{
FILE * HASHDISK = fopen(HashDisk, "rb");
int maxBkt = 30;
int maxSlot = 3;
for (int i = 0; i < maxBkt; i++)
{
for (int j = 0; j < maxSlot; j++)
{
fwrite(ht.pBkt[i].entry[j].key,11,sizeof(maxSlot),HASHDISK);
fwrite(ht.pBkt[i].entry[j].data,21,sizeof(maxSlot),HASHDISK);
}
}
}
void ReportHT (HASHTABLE ht, char * when)
{
int maxB = 30;
int maxS = 3;
cout << "Hash Table \n" << "Verification Report \n" << when << " Restoration" << endl;
for (int b = 0; b < maxB; b++)
{
cout << "Bucket " << (b+1) << endl;
if (b < 20)
{
for (int i = 0; i < maxS; i++)
{
cout << setw(3) << "Slot " << (i+1) << ": " << ht.pBkt[b].entry[i].key << setw(3) << ht.pBkt[b].entry[i].data << endl;
}
}
else
{
for (int i = 0; i < maxS; i++)
{
cout << setw(3) << "Slot " << (i+1) << ": " << ht.oBkt[b].entry[i].key << setw(3) << ht.oBkt[b].entry[i].data << endl;
}
}
}
}
The code compiles with no problems, but when I inspect the file, I find that it is all just gibberish and weird symbols. The data I am using was previously extracted from another file and I want to save it in the format in which it was inserted. I am sure the issue is with the lines with fwrite (I am not that experienced with C syntax as I am with C++).
The data was in the DATAIN.dat file like this:
TATUNG CO.EL PR. LONG BEACH CA
KAMERMAN LCIRRUS BEAVERTON, OR
QUADRAM COLOACH AV NORCROSS GE
AST RESEARALTON AV IRVINE CA
I am expecting the new file to look like this:
TATUNG CO.
EL PR. LONG BEACH CA
KAMERMAN L
CIRRUS BEAVERTON, OR
QUADRAM CO
LOACH AV NORCROSS GE
AST RESEAR
ALTON AV IRVINE CA
Any help would be greatly appreciated. Thank you.
It looks like your code doesn't initialize or even use the member count. When a hash bucket is empty, the count should indicate it. In C++ it's easy to implement: just add = 0 to its definition:
struct BUCKET
{
SLOT entry[3];
int count = 0;
BUCKET* overflow;
};
Also, when writing the bucket's data to a file, use the count and don't assume that all the entries in the bucket are filled.
for (int j = 0; j < ht.pBkt[i].count; j++)
...
Also, write only the required number of bytes. fwrite accepts two parameters: the size of the data elements to write and their number. Here, the size is 11 or 21, and the number is 1, because each fwrite call can only write one string to your file.
fwrite(ht.pBkt[i].entry[j].key,11,1,HASHDISK);
fwrite(ht.pBkt[i].entry[j].data,21,1,HASHDISK);
By the way, since you have a STR10 type, you can avoid magic numbers and write sizeof(STR10) instead of 11. This way, when you change the length of your string, your code will still work.

C++ Reading back "incorrect" values from binary file?

The project I'm working on, as a custom file format consisting of the header of a few different variables, followed by the pixel data. My colleagues have developed a GUI, where processing, writing reading and displaying this type of file format works fine.
But my problem is, while I have assisted in writing the code for writing data to disk, I cannot myself read this kind of file and get satisfactorily values back. I am able to read the first variable back (char array) but not the following value(s).
So the file format matches the following structure:
typedef struct {
char hxtLabel[8];
u64 hxtVersion;
int motorPositions[9];
int filePrefixLength;
char filePrefix[100];
..
} HxtBuffer;
In the code, I create an object of the above structure and then set these example values:
setLabel("MY_LABEL");
setFormatVersion(3);
setMotorPosition( 2109, 5438, 8767, 1234, 1022, 1033, 1044, 1055, 1066);
setFilePrefixLength(7);
setFilePrefix( string("prefix_"));
setDataTimeStamp( string("000000_000000"));
My code for opening the file:
// Open data file, binary mode, reading
ifstream datFile(aFileName.c_str(), ios::in | ios::binary);
if (!datFile.is_open()) {
cout << "readFile() ERROR: Failed to open file " << aFileName << endl;
return false;
}
// How large is the file?
datFile.seekg(0, datFile.end);
int length = datFile.tellg();
datFile.seekg(0, datFile.beg);
cout << "readFile() file " << setw(70) << aFileName << " is: " << setw(15) << length << " long\n";
// Allocate memory for buffer:
char * buffer = new char[length];
// Read data as one block:
datFile.read(buffer, length);
datFile.close();
/// Looking at the start of the buffer, I should be seeing "MY_LABEL"?
cout << "buffer: " << buffer << " " << *(buffer) << endl;
int* mSSX = reinterpret_cast<int*>(*(buffer+8));
int* mSSY = reinterpret_cast<int*>(&buffer+9);
int* mSSZ = reinterpret_cast<int*>(&buffer+10);
int* mSSROT = reinterpret_cast<int*>(&buffer+11);
int* mTimer = reinterpret_cast<int*>(&buffer+12);
int* mGALX = reinterpret_cast<int*>(&buffer+13);
int* mGALY = reinterpret_cast<int*>(&buffer+14);
int* mGALZ = reinterpret_cast<int*>(&buffer+15);
int* mGALROT = reinterpret_cast<int*>(&buffer+16);
int* filePrefixLength = reinterpret_cast<int*>(&buffer+17);
std::string filePrefix; std::string dataTimeStamp;
// Read file prefix character by character into stringstream object
std::stringstream ss;
char* cPointer = (char *)(buffer+18);
int k;
for(k = 0; k < *filePrefixLength; k++)
{
//read string
char c;
c = *cPointer;
ss << c;
cPointer++;
}
filePrefix = ss.str();
// Read timestamp character by character into stringstream object
std::stringstream timeStampStream;
/// Need not increment cPointer, already pointing # 1st char of timeStamp
for (int l= 0; l < 13; l++)
{
char c;
c = * cPointer;
timeStampStream << c;
}
dataTimeStamp = timeStampStream.str();
cout << 25 << endl;
cout << " mSSX: " << mSSX << " mSSY: " << mSSY << " mSSZ: " << mSSZ;
cout << " mSSROT: " << mSSROT << " mTimer: " << mTimer << " mGALX: " << mGALX;
cout << " mGALY: " << mGALY << " mGALZ: " << mGALZ << " mGALROT: " << mGALROT;
Finally, what I see is here below. I added the 25 just to double check that not everything was coming out in hexadecimal. As you can see, I am able to see the label "MY_LABEL" as expected. But the 9 motorPositions all come out looking suspiciously like addresses are not values. The file prefix and the data timestamp (which should be strings, or at least characters), are just empty.
buffer: MY_LABEL M
25
mSSX: 0000000000000003 mSSY: 00000000001BF618 mSSZ: 00000000001BF620 mSSROT: 00000000001BF628 mTimer: 00000000001BF630 mGALX: 00000000001BF638 mGALY: 00000000001BF640 mGALZ: 00000000001BF648 mGALROT: 00000000001BF650filePrefix: dataTimeStamp:
I'm sure the solution can't be too complicated, but I reached a stage where I had this just spinning and I cannot make sense of things.
Many thanks for reading this somewhat long post.
-- Edit--
I might hit the maximum length allowed for a post, but just in case I thought I shall post the code that generates the data that I'm trying to read back:
bool writePixelOutput(string aOutputPixelFileName) {
// Write pixel histograms out to binary file
ofstream pixelFile;
pixelFile.open(aOutputPixelFileName.c_str(), ios::binary | ios::out | ios::trunc);
if (!pixelFile.is_open()) {
LOG(gLogConfig, logERROR) << "Failed to open output file " << aOutputPixelFileName;
return false;
}
// Write binary file header
string label("MY_LABEL");
pixelFile.write(label.c_str(), label.length());
pixelFile.write((const char*)&mFormatVersion, sizeof(u64));
// Include File Prefix/Motor Positions/Data Time Stamp - if format version > 1
if (mFormatVersion > 1)
{
pixelFile.write((const char*)&mSSX, sizeof(mSSX));
pixelFile.write((const char*)&mSSY, sizeof(mSSY));
pixelFile.write((const char*)&mSSZ, sizeof(mSSZ));
pixelFile.write((const char*)&mSSROT, sizeof(mSSROT));
pixelFile.write((const char*)&mTimer, sizeof(mTimer));
pixelFile.write((const char*)&mGALX, sizeof(mGALX));
pixelFile.write((const char*)&mGALY, sizeof(mGALY));
pixelFile.write((const char*)&mGALZ, sizeof(mGALZ));
pixelFile.write((const char*)&mGALROT, sizeof(mGALROT));
// Determine length of mFilePrefix string
int filePrefixSize = (int)mFilePrefix.size();
// Write prefix length, followed by prefix itself
pixelFile.write((const char*)&filePrefixSize, sizeof(filePrefixSize));
size_t prefixLen = 0;
if (mFormatVersion == 2) prefixLen = mFilePrefix.size();
else prefixLen = 100;
pixelFile.write(mFilePrefix.c_str(), prefixLen);
pixelFile.write(mDataTimeStamp.c_str(), mDataTimeStamp.size());
}
// Continue writing header information that is common to both format versions
pixelFile.write((const char*)&mRows, sizeof(mRows));
pixelFile.write((const char*)&mCols, sizeof(mCols));
pixelFile.write((const char*)&mHistoBins, sizeof(mHistoBins));
// Write the actual data - taken out for briefy sake
// ..
pixelFile.close();
LOG(gLogConfig, logINFO) << "Written output histogram binary file " << aOutputPixelFileName;
return true;
}
-- Edit 2 (11:32 09/12/2015) --
Thank you for all the help, I'm closer to solving the issue now. Going with the answer from muelleth, I try:
/// Read into char buffer
char * buffer = new char[length];
datFile.read(buffer, length);// length determined by ifstream.seekg()
/// Let's try HxtBuffer
HxtBuffer *input = new HxtBuffer;
cout << "sizeof HxtBuffer: " << sizeof *input << endl;
memcpy(input, buffer, length);
I can then display the different struct variables:
qDebug() << "Slice BUFFER label " << QString::fromStdString(input->hxtLabel);
qDebug() << "Slice BUFFER version " << QString::number(input->hxtVersion);
qDebug() << "Slice BUFFER hxtPrefixLength " << QString::number(input->filePrefixLength);
for (int i = 0; i < 9; i++)
{
qDebug() << i << QString::number(input->motorPositions[i]);
}
qDebug() << "Slice BUFFER filePrefix " << QString::fromStdString(input->filePrefix);
qDebug() << "Slice BUFFER dataTimeStamp " << QString::fromStdString(input->dataTimeStamp);
qDebug() << "Slice BUFFER nRows " << QString::number(input->nRows);
qDebug() << "Slice BUFFER nCols " << QString::number(input->nCols);
qDebug() << "Slice BUFFER nBins " << QString::number(input->nBins);
The output is then mostly as expected:
Slice BUFFER label "MY_LABEL"
Slice BUFFER version "3"
Slice BUFFER hxtPrefixLength "2"
0 "2109"
1 "5438"
...
7 "1055"
8 "1066"
Slice BUFFER filePrefix "-1"
Slice BUFFER dataTimeStamp "000000_000000P"
Slice BUFFER nRows "20480"
Slice BUFFER nCols "256000"
Slice BUFFER nBins "0"
EXCEPT, dataTimeStamp, which is 13 chars long, displays instead 14 chars. The 3 variables that follow: nRows, nCols and nBins are then incorrect. (Should be nRows=80, nCols=80, nBins=1000). My guess is that the bits belonging to the 14th char of dataTimeStamp should be read along with nRows, and so cascade on to produce the correct nCols and nBins.
I have separately verified (not shown here) using qDebug that what I'm writing into the file, really are the values I expect, and their individual sizes.
I personally would try to read exactly the number of bytes your struct is from the file, i.e. something like
int length = sizeof(HxtBuffer);
and then simply use memcpy to assign a local structure from the read buffer:
HxtBuffer input;
memcpy(&input, buffer, length);
You can then access your data e.g. like:
std::cout << "Data: " << input.hxtLabel << std::endl;
Why do you read to buffer, instead of using the structure for reading?
HxtBuffer data;
datFile.read(reinterpret_cast<char *>(&data), sizeof data);
if(datFile && datFile.gcount()!=sizeof data)
throw io_exception();
// Can use data.
If you want to read to a chracter buffer, than your way of getting the data is just wrong. You probably want to do something like this.
char *buf_offset=buffer+8+sizeof(u64); // Skip label (8 chars) and version (int64)
int mSSX = *reinterpret_cast<int*>(buf_offset);
buf_offset+=sizeof(int);
int mSSY = *reinterpret_cast<int*>(buf_offset);
buf_offset+=sizeof(int);
int mSSZ = *reinterpret_cast<int*>(buf_offset);
/* etc. */
Or, a little better (provided you don't change the contents of the buffer).
int *ptr_motors=reinterpret_cast<int *>(buffer+8+sizeof(u64));
int &mSSX = ptr_motors[0];
int &mSSY = ptr_motors[1];
int &mSSZ = ptr_motors[2];
/* etc. */
Notice that I don't declare mSSX, mSSY etc. as pointers. Your code was printing them as addresses because you told the compiler that they were addresses (pointers).

Modulo creating bad int for addresses in Hash Table?

HELP! I'm trying to create a hash table using Separate Chaining. For some unknown reason I cant seem to traverse and find all the original int I loaded. I suspect the modulo function is giving me bad addresses sometimes in both functions. First creating bad addresses on assorted int when creating the hash table and then sometimes searching the wrong addresses in the second function while attempting to traverse and confirm my list using modulo again. The hash table is populated by a basic random array of numbers and then I compare the created hash table with the original random array of int. Here is what I believe the culprit is causing all my troubles but I cant be 100% sure:
address = randARRAY[key] % MAX_KEYS;
And here is the function for creating the Hash Table using Separate Chaining. I generally have MAX_KEYS = 5000, tbSIZE = 8989, which is better than 75% Load factor somewhere around 55%:
void separateCHAINING(int *randARRAY,int tbSIZE,TABLE *head[]){
int key = 0,
address = 0,
collisions = 0,
newONE = 0;
randARRAY[MAX_KEYS + 1] = 0;
TABLE *newADDRESS[tbSIZE];
newADDRESS[tbSIZE] = new TABLE();
for(int a = 0; a < tbSIZE; a++){
newADDRESS[a] = NULL;
head[a] = NULL;
}
while(randARRAY[key] != 0){
address = randARRAY[key] % MAX_KEYS;
newADDRESS[address] = new TABLE;
newADDRESS[address]->key = randARRAY[key];
if(head[address] != 0){
newADDRESS[address]->next = head[address]->next;
head[address]->next = newADDRESS[address];
collisions++;
}
else{
newADDRESS[address]->next = head[address];
head[address] = newADDRESS[address];
newONE++;
}
key++;
}
cout << "total collisions: " << collisions << endl;
cout << "new: " << newONE << endl;
cout << "added: " << collisions + newONE << endl;
cout << "key: " << key << endl;
}
This created data appears to be passed without issue. I used gdb to create a ridiculously long list on one array index and it was all there in the second function without missing any nodes. This is why I think the addresses might be getting botched by modulo in both the function above and on this one below. This is apparently creating bogus addresses and then calling the wrong ones later. In the end Im never able to find all my int for the random array put in the Hash Table. Here is the function which uses modulo again and then tries to traverse and match the random array against the new hash table:
void tableTWO_MATCH(int *randARRAY,TABLE *HT_TWO[]){
int key = 0,
address = 0,
match = 0,
nomatch = 0;
randARRAY[MAX_KEYS + 1] = 0;
while(randARRAY[key] != 0){
address = randARRAY[key] % MAX_KEYS;
while(HT_TWO[address]->next != NULL && HT_TWO[address]->key != randARRAY[key]){
HT_TWO[address] = HT_TWO[address]->next;
}//end second while
if(HT_TWO[address]->key == randARRAY[key]){
match++;
}//end if
if(HT_TWO[address]->key != randARRAY[key]){
nomatch++;
}//end if
key = key + 1;
address = 0;
}//end outer while
cout << "match: " << match << endl;
cout << "not match: " << nomatch << endl;
cout << "key: " << key << endl;
}
As always thank you ahead of time for any assistance! I will be grateful if you can see where I'm messing up!
Well I guess I'm just a bone head! I used a boolean variable to check and see if a match was found at any point in time during traversal.
if(HT_TWO[address]->key == randARRAY[key]){
found = true;
}
I was trying to match nodes that had traversed past their match and getting poor results. Anyway This is how I changed my verification using boolen instead. Thanks for your help guys!
void tableTWO_MATCH(int *randARRAY,TABLE *HT_TWO[]){
int key = 0,
address = 0,
match = 0,
nomatch = 0;
bool found = false;
randARRAY[MAX_KEYS + 1] = 0;
while(randARRAY[key] != 0){
address = HASH(randARRAY[key],MAX_KEYS);
if(HT_TWO[address]->key == randARRAY[key]){
match++;
}
else{
while(HT_TWO[address]->next != NULL){
HT_TWO[address] = HT_TWO[address]->next;
if(HT_TWO[address]->key == randARRAY[key]){
found = true;
}
}//end second while
if(found == false){
nomatch++;
}
}
key = key + 2;
}//end outer while
cout << "not match: " << nomatch << endl;
cout << "key: " << key << endl;
}