int main(){
int V1;
float V2;
bool V3 = true;
int *Ptr1;
int *Ptr2;
*Ptr1 = V1;
*Ptr2 = V2;
cout << "Enter the worth of V1: " << endl;
cin >> *Ptr1;
cout << "Enter the worth of V2: " << endl;
cin >> *Ptr2;
int *Ptr3 = &Ptr1 - &Ptr2;
cout << Ptr3;
}
My problem is that when i declare the variables i have to put one float and one int, so the program donĀ“t let me substract a float with an int.
int *Ptr1;
int *Ptr2;
*Ptr1 = V1;
*Ptr2 = V2;
This is undefined behavior. Ptr1 and Ptr2 are uninitialized, but you attempt to dereference them in the assignment statements. You are trying to write values into random (uninitialized) memory locations.
int *Ptr3 = &Ptr1 - &Ptr2;
Here you use the & operator to take the addresses of Ptr1 and Ptr2 (which are already pointers!), then try to subtract the addresses, and use
that to initialize Ptr3.
None of this makes any sense. You seem to be misunderstanding how pointers,
the & operator, and the * operator work. Better make another pass through whatever reference materials you're working from...
Related
For the quick sort algorithm(recursive), every time when it calls itself, it have the condition if(p < r). Please correct me if I am wrong: as far as I know, for every recursive algorithm, it has a condition as the time when it entered the routine, and this condition is used to get the base case. But I still cannot understand how to correctly set and test this condition ?
void quickSort(int* arr, int p, int r)
{
if(p < r)
{
int q = partition(arr,p,r);
quickSort(arr,p,q-1);
quickSort(arr,q+1,r);
}
}
For my entire code, please refer to the following:
/*
filename : main.c
description: quickSort algorithm
*/
#include<iostream>
using namespace std;
void exchange(int* val1, int* val2)
{
int temp = *val1;
*val1 = *val2;
*val2 = temp;
}
int partition(int* arr, int p, int r)
{
int x = arr[r];
int j = p;
int i = j-1;
while(j<=r-1)
{
if(arr[j] <= x)
{
i++;
// exchange arr[r] with arr[j]
exchange(&arr[i],&arr[j]);
}
j++;
}
exchange(&arr[i+1],&arr[r]);
return i+1;
}
void quickSort(int* arr, int p, int r)
{
if(p < r)
{
int q = partition(arr,p,r);
quickSort(arr,p,q-1);
quickSort(arr,q+1,r);
}
}
// driver program to test the quick sort algorithm
int main(int argc, const char* argv[])
{
int arr1[] = {13,19,9,5,12,8,7,4,21,2,6,11};
cout <<"The original array is: ";
for(int i=0; i<12; i++)
{
cout << arr1[i] << " ";
}
cout << "\n";
quickSort(arr1,0,11);
//print out the sorted array
cout <<"The sorted array is: ";
for(int i=0; i<12; i++)
{
cout << arr1[i] << " ";
}
cout << "\n";
cin.get();
return 0;
}
Your question is not quite clear, but I will try to answer.
Quicksort works by sorting smaller and smaller arrays. The base case is an array with less than 2 elements because no sorting would be required.
At each step it finds a partition value and makes it true that all the values to the left of the partition value are smaller and all values to the right of the partition value are larger. In other words, it puts the partition value in the correct place. Then it recursively sorts the array to the left of the partition and the array to right of the partition.
The base case of quicksort is an array with one element because a one element array requires no sorting. In your code, p is the index of the first element and r is the index of the last element. The predicate p < r is only true for an array of at least size 2. In other words, if p >= r then you have an array of size 1 (or zero, or nonsense) and there is no work to do.
In an MPI application I have a distributed array of floats and two "parallel" arrays of integers: for each float value there are two associated integers that describe the corresponding value. For the sake of cache-efficiency I want to treat them as three different arrays, i.e. as a structure of arrays, rather than an array of structures.
Now, I have to gather all these values into the first node. I can do this in just one communication instruction, by defining an MPI type, corresponding to a structure, with one float and two integers. But this would force me to use the array of structures pattern instead of the structure of arrays one.
So, I can choose between:
Performing three different communications, one for each array and keep the efficient structure of arrays arrangement
Defining an MPI type, perform a single communication, and deal with the resulting array of structures by adjusting my algorithm or rearranging the data
Do you know a third option that would allow me do have the best of both worlds, i.e. having a single communication and keeping the cache-efficient configuration?
You take take a look at Packing and Unpacking.
http://www.mpi-forum.org/docs/mpi-11-html/node62.html
However, I think if you want to pass a same "structure" often you should define you own MPI derivate type.
E.g. by using the *array_of_blocklength* parameter of MPI_Type_create_struct
// #file mpi_compound.cpp
#include <iterator>
#include <cstdlib> // for rng
#include <ctime> // for rng inits
#include <iostream>
#include <algorithm>
#include <mpi.h>
const std::size_t N = 10;
struct Asset {
float f[N];
int m[N], n[N];
void randomize() {
srand(time(NULL));
srand48(time(NULL));
std::generate(&f[0], &f[0] + N, drand48);
std::generate(&n[0], &n[0] + N, rand);
std::generate(&m[0], &m[0] + N, rand);
}
};
int main(int argc, char* argv[]) {
MPI_Init(&argc,&argv);
int rank,comm_size;
MPI_Status stat;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&comm_size);
Asset a;
MPI_Datatype types[3] = { MPI_FLOAT, MPI_INT, MPI_INT };
int bls[3] = { N, N, N };
MPI_Aint disps[3];
disps[0] = 0;
disps[1] = int(&(a.m[0]) - (int*)&a)*sizeof(int);
disps[2] = int(&(a.n[0]) - (int*)&a)*sizeof(int);
MPI_Datatype MPI_USER_ASSET;
MPI_Type_create_struct(3, bls, disps, types, &MPI_USER_ASSET);
MPI_Type_commit(&MPI_USER_ASSET);
if(rank==0) {
a.randomize();
std::copy(&a.f[0], &a.f[0] + N, std::ostream_iterator<float>(std::cout, " "));
std::cout << std::endl;
std::copy(&a.m[0], &a.m[0] + N, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
std::copy(&a.n[0], &a.n[0] + N, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
MPI_Send(&a.f[0],1,MPI_USER_ASSET,1,0,MPI_COMM_WORLD);
} else {
MPI_Recv(&a.f[0],1,MPI_USER_ASSET,0,0,MPI_COMM_WORLD, &stat);
std::cout << "\t=> ";
std::copy(&a.f[0], &a.f[0] + N, std::ostream_iterator<float>(std::cout, " "));
std::cout << std::endl << "\t=> ";
std::copy(&a.m[0], &a.m[0] + N, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl << "\t=> ";
std::copy(&a.n[0], &a.n[0] + N, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
MPI_Type_free(&MPI_USER_ASSET);
MPI_Finalize();
return 0;
}
worked with
mpirun -n 2 ./mpi_compound
with mpich2 v1.5 (HYDRA) on x86_86 linux and g++ 4.4.5-8 - based mpic++
I update segment tree with such function. Profiling says here's the bottleneck:
void update (int tree[], int root, int left, int right, int pos, double val)
{
if (left == right)
{
data[tree[root]] = val;
}
else
{
int middle = (left + right) / 2;
if (pos <= middle)
update(tree, root*2, left, middle, pos, val);
else
update(tree, root*2+1, middle+1, right, pos, val);
tree[root] = indexOfMax(tree, tree[root*2], tree[root*2+1]); // simple comparations
}
}
// indexOfMax is just a simple comparation
int indexOfMax(int tree[], int a, int b)
{
//cout << data[tree[a]] << " > " << data[tree[b]] << " ? " << tree[a] << " : " << tree[b] << endl;
return data[a] > data[b] ? a : b;
}
And while memory operations are fast, I'm wondering if it is caused by recursion overhead, while the depth of it is usually not more 20.
What I get from my primitive profiler is:
4.39434ms - average time for a singe binary search over data
2642.94ms - time from a single update
19.9097ms - time for a single RMQ-query.
So.. The time spent on a single update is dramatic :).
Answer : one hidden std::find over map was found.
I am using QT 4.8 and I notice that it has a QHash class which can be used as follows:
QHash<QString, int> hash;
hash["one"] = 1;
hash["three"] = 3;
hash["seven"] = 7;
hash.insert("twelve", 12);
If there is a hash collision, will it be handled correctly?
Yes, collisions will be handled. QHash is a standard implementation of the classic hash-table based container and wouldn't be very reliable if it didn't handle collisions correctly. Typically a hash-table based container will map keys not to a single entry in the list but to a "bucket" which may contain more than one entry where different keys map to the same hash value.
When fetching values, the hash value for the key leads to the correct bucket then the container will iterate through the entries in the bucket until it finds a match for the particular key you are looking for.
Although I could not find a specific reference in the documentation to the "correctness" of Qt's implementation, this quote eludes to it. I can't imagine it being otherwise.
QHash's internal hash table grows by powers of two, and each time it
grows, the items are relocated in a new bucket, computed as qHash(key)
% QHash::capacity() (the number of buckets).
A simple test will increase our confidence:
BadHashOjbect.h
#ifndef BADHASHOBJECT_H
#define BADHASHOBJECT_H
class BadHashObject
{
public:
BadHashObject(const int value): value(value){}
int getValue() const
{
return value;
}
private:
int value;
};
bool operator==(const BadHashObject &b1, const BadHashObject &b2)
{
return b1.getValue() == b2.getValue();
}
uint qHash(const BadHashObject &/*key*/)
{
return 1;
}
#endif // BADHASHOBJECT_H
main.cpp
#include <iostream>
#include <QHash>
#include "BadHashObject.h"
using namespace std;
int main(int , char **)
{
cout << "Hash of BadHashObject(10) is: " << qHash(BadHashObject(10)) << endl;
cout << "Hash of BadHashObject(100) is: " << qHash(BadHashObject(100)) << endl;
cout << "Adding BadHashObject(10), value10 and BadHashObject(100), value100" << endl;
QHash<BadHashObject, QString> hashMap;
hashMap.insert(BadHashObject(10), QString("value10"));
hashMap.insert(BadHashObject(100), QString("value100"));
cout << "Size of hashMap: " << hashMap.size() << endl;
cout << "Value stored with key 10: " << hashMap.value(BadHashObject(10)).toStdString() << endl;
cout << "Value stored with key 100: " << hashMap.value(BadHashObject(100)).toStdString() << endl;
}
The BadHashObject class stores an int and its hash function will always return 1 so all objects added to a QHash using this type as a key will result in a collision. The output from our test program shows that the collision is handled properly.
Hash of BadHashObject(10) is: 1
Hash of BadHashObject(100) is: 1
Adding BadHashObject(10), value10 and BadHashObject(100), value100
Size of hashMap: 2
Value stored with key 10: value10
Value stored with key 100: value100
How do I pass a struct through the pthread_create to my function? The errors I keep getting are that lower and upper has not been defined which would lead me to believe that the struct was not passed properly. I have tried referencing lower as arg1.lower and my error back is saying im trying to request for the member of a non class type void*
void * mergeSortThread(void *arg1){
std::ostringstream ostr;
ostr << "begin: " << lower << " " << upper << endl;
string message = ostr.str();
write(2, message.data(), message.length());
}
int main(int argc, char** argv)
{
struct MergeSortThreadArg
{
int * array;
int * temp;
int lower, upper;
};
pthread_attr_t attr;
pthread_attr_init(&attr);
int arr[20];
int temp[20];
MergeSortThreadArg arg;
arg.array = arr;
arg.temp = temp;
arg.lower = 0;
arg.upper = 19;
pthread_create(th, &attr, mergeSortThread, &arg);
pthread_join(th[z], NULL);
return 0;
}
Define struct before mergeSortThread() and add casting of arg1 to struct MergeSortThreadArg * it in mergeSortThread():
void * mergeSortThread(void *arg1){
struct MergeSortThreadArg *p_MST = (struct MergeSortThreadArg *)arg1;
std::ostringstream ostr;
ostr << "begin: " << p_MST->lower << " " << p_MST->upper << endl;
...
Moreover, it's more correct/safe to allocate the struct and its fields (array and tmp) to avoid passing to new thread data located on stack of another thread.