I am try to write a container memcpy function.
However, I can't pass my container as parameter.
Could anyone give me a hint?
At this moment, I create 1 more function inside class called DIn, to put information.
I try to achieve remove DIn function, and use like normal memory copy to do this.
Could somebody give me a help?
Best regards
TINGMING
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
template <typename VECTOR_TYPE = char,int VECTOR_SIZE = 256>
class vector{
private:
int SIZE;
VECTOR_TYPE ARRAY[VECTOR_SIZE];
public:
vector():SIZE(VECTOR_SIZE){
}
VECTOR_TYPE& operator[](int nIndex){
assert(nIndex >= 0 && nIndex < SIZE);
return ARRAY[nIndex];
}
void DIn(VECTOR_TYPE data,int nIndex){
assert(nIndex >= 0 && nIndex < SIZE);
ARRAY[nIndex] = data;
}
int sizeof_vector(){
return SIZE;
}
};
template <typename VECTOR_TYPE,int VECTOR_SIZE1,int VECTOR_SIZE2>
void vector_memcpy(
vector <VECTOR_TYPE,VECTOR_SIZE1> *target,int tIdx,
vector <VECTOR_TYPE,VECTOR_SIZE2> source,int sIdx,
int Length)
{
int i;
for(i=0;i<Length;i++)
target->DIn(source[sIdx+i],tIdx+i);
}
int main()
{
vector <int,16> AV;
vector <int,32> BV;
int i;
for(i=0;i<16;i++)
AV[i] = i*15;
vector_memcpy(&BV,0,AV,0,16);
vector_memcpy(&BV,16,BV,0,16);
for(i=0;i<16;i++)
printf("%2d: %3d %3d %3d\n",i,AV[i],BV[i],BV[i+16]);
return 0;
}
Related
I need help... appropriate questions have been asked in the comments. The programs has zero compiler errors and warnings!! I have concerns with calling a member function from another member function using function pointers. (To be precise, setMatrixto() is trying to call setElement() function using function pointer)
Plus somehow the "hello there" is not being printed to the console. I was expecting it to show up as output.Maybe the setMatrixto() is not getting called at all!!
Header File definition
#ifndef MATRIXOPERATIONS_H
#define MATRIXOPERATIONS_H
class MatrixOperations;
typedef int (MatrixOperations::*INTFUNC)(int,int);
typedef void (MatrixOperations::*VOIDFUNC)(int,int,int);
class MatrixOperations
{
public:
MatrixOperations();
MatrixOperations(int size);
~MatrixOperations();
//diagonal matrix funtions
void displayMatrixOf(INTFUNC f);
void setMatrixTo(VOIDFUNC f);
int getElement(INTFUNC from, int i, int j);
void setElement(VOIDFUNC to,int i ,int j, int value);
int fromDiagonalArray(int i, int j);
void toDiagonalArray(int i, int j, int value);
protected:
private:
int size;
int* a;
};
#endif // MATRIXOPERATIONS_H
CPP Implementation File
#include "MatrixOperations.h"
#include <iostream>
using namespace std;
MatrixOperations::MatrixOperations()
{
//ctor
size = 3;
a = new int[size];
}
MatrixOperations::MatrixOperations(int size)
{
//ctor
this->size = size;
a = new int[size];
}
MatrixOperations::~MatrixOperations()
{
//dtor
delete[] a;
}
///////////////////FUCNTION POINTER SECTION///////////////////////////////////
int MatrixOperations::getElement(INTFUNC from, int i, int j)
{
return (this->*from)(i,j);
}
void MatrixOperations::setElement(VOIDFUNC to,int i ,int j, int value)
{
(this->*to)(i,j,value);
}
/////////////////////////////////DIAGONAL ARRAY OPERATIONS/////////////////////////////////////////////////
int MatrixOperations::fromDiagonalArray(int i, int j)
{
if(i==j)
{
return a[i];
}
else
{
return 0;
}
}
void MatrixOperations::toDiagonalArray(int i, int j, int value)
{
a[i] = value;
}
///////////////////////////////////////////////////////////////////
void MatrixOperations::displayMatrixOf(INTFUNC f)
{
for(int i{0}; i < size; i++)
{
for(int j{0}; j < size; j++)
{
cout << getElement(f,i,j) << "\t"; //is this the correct way to send the function pointer?
}
cout << endl;
}
}
void MatrixOperations::setMatrixTo(VOIDFUNC f)
{
cout << "Hello there!!"; //not getting this output.. whats wrong??
for(int i{0}; i < size; i++)
{
int value {};
cout << "Enter value diagonal element " << i << " : ";
cin >> value;
setElement(f,i,i,value); //is this the correct way to send the function pointer?
}
}
///////////////////////////////////////////////////////////////////////////////
Main File
#include <iostream>
#include "MatrixOperations.h"
typedef MatrixOperations MATRIX;
using namespace std;
int main()
{
MATRIX m1;
m1.setMatrixTo(MATRIX::toDiagonalArray); //was expecting a "Hello there!" but i am not getting that output either
return 0;
}
EDIT2: I added all the class definitions and main function in one single file. SURPRISINGLY!! this works . I am confused??!!!
#include <iostream>
using namespace std;
class MatrixOperations;
typedef void (MatrixOperations::*VOIDFUNC)(int,int,int);
typedef MatrixOperations MATRIX;
class MatrixOperations
{
public:
MatrixOperations();
MatrixOperations(int size);
~MatrixOperations();
//diagonal matrix funtions
void setMatrixTo(VOIDFUNC f);
void setElement(VOIDFUNC to,int i ,int j, int value);
void toDiagonalArray(int i, int j, int value);
private:
int size;
int* a;
};
MatrixOperations::MatrixOperations()
{ //ctor
size = 3;
a = new int[size];
}
MatrixOperations::MatrixOperations(int size)
{ //ctor
this->size = size;
a = new int[size];
}
MatrixOperations::~MatrixOperations()
{
//dtor
delete[] a;
}
void MatrixOperations::setElement(VOIDFUNC to,int i ,int j, int value)
{
(this->*to)(i,j,value);
}
/////////////////////////////////DIAGONAL ARRAY OPERATIONS/////////////////////////////////////////////////
void MatrixOperations::toDiagonalArray(int i, int j, int value)
{
a[i] = value;
}
///////////////////////////////////////////////////////////////////
void MatrixOperations::setMatrixTo(VOIDFUNC f)
{
cout << "Hello there!!" << endl;
for(int i{0}; i < size; i++)
{
int value {};
cout << "Enter value diagonal element " << i << " : ";
cin >> value;
setElement(f,i,i,value);
}
}
int main()
{
MATRIX m1;
m1.setMatrixTo(MATRIX::toDiagonalArray);
return 0;
}
There is nothing wrong with the code in both cases. Its just my debugger was not running in admin mode. I got error code 740. So I launched my IDE in admin mode and voila it worked.
In the class constructor, I am initializing other objects and pushing these objects to my class vector member. From what I understand, the vector create a copy of the object and stores it so that it doesn't go out of scope. However, when verifying the objects in another class function, they are not initialized anymore. Here's a example code to explain the behaviour:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Square {
private:
int size_ = 0;
int colour_ = 0;
public:
Square(){
size_ = 0;
colour_ = 0;
}
void init(int size, int colour) {
size_ = size;
colour_ = colour;
}
int get_size() { return size_; }
};
class SetSquares {
private:
std::vector<Square> squares_;
int number_;
public:
SetSquares(): number_(0) {}
void init(int num) {
number_ = num;
squares_.clear();
squares_.resize(num);
for (int i=0; i < num; i++) {
Square square;
square.init(i, i);
squares_.push_back(square);
}
}
void sample(int i) {
if (i >= number_) { return; }
std::cout << "Square size is: " << squares_[i].get_size() << std::endl;
}
};
int main()
{
SetSquares set_of_squares;
set_of_squares.init(7);
set_of_squares.sample(4);
return 0;
}
resize(n) will create n default constructed elements in a vector and push_back will append new elements after those n elements. Use reserve and push_back or resize and index operator as suggested in comment.
I'm trying to overload the addition operator but I keep getting a segmentation fault even though I'm passing in the argument by value after it's memory has been deallocated. Anybody have any idea what I could be doing wrong. Also once I get this running properly after fixing the overloaded addition, I need to use vectors instead of pointing to arrays which I have no idea how to declare in a manner equivalent to what I've wrritten for arrays.
RowAray.h
#ifndef ROWARAY_H // if constant ROWARAY_H not defined do not execute
#define ROWARAY_H // defines constant ROWARAY_H
#include <new> // Needed for bad_alloc exception
#include <cstdlib> // Needed for the exit function
template <class T>
class RowAray{
private:
int size;
T *rowData;
void memError(); // Handles memory allocation errors
void subError(); // Handles subscripts out of range
public:
RowAray(T); //used to construct row Array object
~RowAray(){delete [] rowData;} //used to deallocate dynamically allocated memory from Row array
int getSize(){return size;} //inline accessor member function used to return length of Row array
void setData(int row, T value);
T getData(int i){return (( i >=0&& i < size)?rowData[i]:0);} //
T &operator[](const int &);
};
template <class T>
RowAray<T>::RowAray(T colSize){
size =colSize>1?colSize:1;
// Allocate memory for the array.
try
{
rowData = new T [size];
}
catch (bad_alloc)
{
memError();
}
// Initialize the array.
for (int count = 0; count < size; count++){
T value = rand()%90+10;
setData(count, value);
}
}
template <class T>
void RowAray<T>::memError()
{
cout << "ERROR:Cannot allocate memory.\n";
exit(EXIT_FAILURE);
}
template <class T>
void RowAray<T>::subError()
{
cout << "ERROR: Subscript out of range.\n";
exit(EXIT_FAILURE);
}
template <class T>
T &RowAray<T>::operator[](const int &sub)
{
if (sub < 0 || sub >= size)
subError();
else
return rowData[sub];
}
template <class T>
void RowAray<T>::setData(int row, T value){
//used to fill array with random 2 digit #s
*(rowData + row) = value;
}
#endif /* ROWARAY_H */
Table.h
#ifndef TABLE_H
#define TABLE_H
#include "RowAray.h"
template <class T>
class Table{
private:
int szRow;
int szCol;
RowAray<T> **records;
public:
Table(int,int); //used to construct Table object
Table(const Table &);
~Table(); //used to deallocate dynamically allocated memory from Table object
int getSzRow() const{return szRow;} //used to return row size
int getSzCol()const {return szCol;}
Table operator+(const Table &);
T getRec(int, int) const; //used to return inserted random numbers of 2d arrays
};
template <class T>
Table<T>::Table(int r, int c ){
//Set the row size
this->szRow = r;
//Declare the record array
records = new RowAray<T>*[this->szRow];
//Size each row
this->szCol = c;
//Create the record arrays
for(int i=0;i<this->szRow;i++){
records[i]=new RowAray<T>(this->szCol);
}
}
template <class T>
Table<T>::Table(const Table &Tab){
szRow=Tab.getSzRow();
szCol=Tab.getSzCol();
records = new RowAray<T>*[szCol];
for(int i = 0; i < this->szCol; i++){
records[i] = new RowAray<T>(szRow);
}
//set elements = to random value
for(int row = 0; row < szRow; row++){
for(int col = 0; col < this->szCol; col++){
int value = Tab.getRec(row, col);
records[col]->setData(row,value);
}
}
}
template <class T>
T Table<T>::getRec(int row, int col) const{
//if else statement used to return randomly generated numbers of array
if(row >= 0 && row < this->szRow && col >= 0 && col < this->szCol){
return records[row]->getData(row);
}else{
return 0;
}
}
template <class T>
Table<T>::~Table(){
//Delete each record
for(int i=0;i<this->szRow;i++){
delete records[i];
}
delete []records;
}
template <class T>
Table<T> Table<T>::operator+(const Table &Tab){
Table temp(Tab.getSzRow(), Tab.getSzCol());
//set elements = to random value for operation to
for(int row=0; row < szRow; row++){
for(int col=0; col < szCol; col++){
int value = getRec(row, col) + Tab.getRec(row, col);
temp.records[col]->setData(row,value);
}
}
return temp;
}
#endif /* TABLE_H */
main.cpp
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
using namespace std;
//User Libraries
#include "Table.h"
//Global Constants
//Function Prototype
template<class T>
void prntRow(T *,int);
template<class T>
void prntTab(const Table<T> &);
//Execution Begins Here!
int main(int argc, char** argv) {
//Initialize the random seed
srand(static_cast<unsigned int>(time(0)));
//Declare Variables
int rows=3,cols=4;
//Test out the Row with integers and floats
RowAray<int> a(3);
RowAray<float> b(4);
cout<<"Test the Integer Row "<<endl;
prntRow(&a,3);
cout<<"Test the Float Row "<<endl;
prntRow(&b,4);
//Test out the Table with a float
Table<float> tab1(rows,cols);
Table<float> tab2(tab1);
Table<float> tab3 = tab1 + tab2;
cout<<"Float Table 3 size is [row,col] = Table 1 + Table 2 ["
<<rows<<","<<cols<<"]";
prntTab(tab3);
//Exit Stage Right
return 0;
}
template<class T>
void prntRow(T *a,int perLine){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int i=0;i<a->getSize();i++){
cout<<a->getData(i)<<" ";
if(i%perLine==(perLine-1))cout<<endl;
}
cout<<endl;
}
template<class T>
void prntTab(const Table<T> &a){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int row=0;row<a.getSzRow();row++){
for(int col=0;col<a.getSzCol();col++){
cout<<setw(8)<<a.getRec(row,col);
}
cout<<endl;
}
cout<<endl;
}
You error stems from line 85 of Table.h, in you + operator overload:
temp.records[col]->setData(row,value);
should really be
temp.records[row]->setData(col,value);
Apart from that, I spotted another error in the same file in line 62 (method Table<T>::getRec(int row, int col)):
return records[row]->getData(row);
should be
return records[row]->getData(col);
Apart from those problems, I would highly advise you to rethink and restructure your code (maybe you could also try a code review), since a large part of it is superfluous in my opinion and some things could become problematic if you expand the project (for example, RowAray's constructor takes a T colSize as parameter where you should probably use an int or, better, a size_t. This code as it is will not work when T is not implicitly convertible to an integer type).
In my code, I have a statically allocated array in global memory (i.e., allocated using __device__), which I want to sort using thrust::sort, which isn't working. All of the examples on this topic are using CUDA runtime allocated arrays (using cudaMalloc). Is there any way I can sort a statically allocated array?
I guess it has something to do with statically allocated memory not being accessible from the host. Using cudaMalloc-allocated arrays, it is working fine. However, I want to avoid using this type of allocation since static allocation allows for easier access to the data from device code (doesn't it?).
Minimal (not-) working example:
#include <stdio.h>
#include <thrust/device_ptr.h>
#include <thrust/sort.h>
#define N 4
typedef struct element {
int key;
int value;
__host__ __device__ bool operator<(element e) const
{ return key > e.key; }
} element;
__device__ element array[N];
__global__ void init() {
for (int i = 0; i < N; ++i) {
array[N - i - 1].key = i;
}
}
__global__ void print_array() {
for (int i = 0; i < N; ++i) {
printf("%d ", array[i].key);
}
printf("\n");
}
int main(void) {
thrust::device_ptr<element> array_first(array);
init<<<1,1>>>();
printf("unsorted: ");
print_array<<<1, 1>>>();
cudaDeviceSynchronize();
thrust::sort(array_first, array_first + N);
printf("sorted: ");
print_array<<<1, 1>>>();
cudaDeviceSynchronize();
}
Use cudaGetSymbolAddress to take the address of the array variable from a __host__ function:
void* array_ptr = 0;
cudaGetSymbolAddress(&array_ptr, array);
thrust::device_ptr<element> array_first(reinterpret_cast<element*>(array_ptr));
Here's the complete program:
#include <stdio.h>
#include <thrust/device_ptr.h>
#include <thrust/sort.h>
#define N 4
typedef struct element {
int key;
int value;
__host__ __device__ bool operator<(element e) const
{ return key > e.key; }
} element;
__device__ element array[N];
__global__ void init() {
for (int i = 0; i < N; ++i) {
array[N - i - 1].key = i;
}
}
__global__ void print_array() {
for (int i = 0; i < N; ++i) {
printf("%d ", array[i].key);
}
printf("\n");
}
int main(void) {
cudaError_t error;
void* array_ptr = 0;
if(error = cudaGetSymbolAddress(&array_ptr, array))
{
throw thrust::system_error(error, thrust::cuda_category());
}
thrust::device_ptr<element> array_first(reinterpret_cast<element*>(array_ptr));
init<<<1,1>>>();
printf("unsorted: ");
print_array<<<1, 1>>>();
if(error = cudaDeviceSynchronize())
{
throw thrust::system_error(error, thrust::cuda_category());
}
thrust::sort(array_first, array_first + N);
if(error = cudaDeviceSynchronize())
{
throw thrust::system_error(error, thrust::cuda_category());
}
printf("sorted: ");
print_array<<<1, 1>>>();
if(error = cudaDeviceSynchronize())
{
throw thrust::system_error(error, thrust::cuda_category());
}
return 0;
}
Here's the output on my system:
$ nvcc test.cu -run
unsorted: 3 2 1 0
sorted: 3 2 1 0
The sorted output is the same as the unsorted output, but I guess that is intentional given the way the data is generated and the definition of element::operator<.
This:
__device__ element array[N];
...
thrust::device_ptr<element> array_first(array);
is illegal. In host code, array is a host address and can't be passed to device code. Do something like this instead:
element* array_d;
cudaGetSymbolAddress((void **)&array_d, array);
thrust::device_ptr<element> array_first(array_d);
i.e. you need to use cudaGetSymbolAddress to read the address from the GPU context at runtime, then you can use the result of that call in GPU code.
I'm using an example code given to me by another C++ coder for a project. I'm a new student of C++ language and I wondered is there a possible memory leak / bugs in this class file given to me (PlacementHead.cpp):
#include "PlacementHead.h"
#include <string>
#include <iostream>
#include <string.h>
PlacementHead::PlacementHead(int width, int height, int gap, char* s) {
width_ = width;
height_ = height;
gap_ = gap;
size_ = (width*height)+1;
set_ = new char[size_ + 1];
from_ = new int[size_ + 1];
original_ = new char[size_ + 1];
strcpy(set_,s);
strcpy(original_,s);
}
PlacementHead::~PlacementHead() {
}
int PlacementHead::getSize() { return size_; }
int PlacementHead::getHeight() { return height_; }
int PlacementHead::getWidth() { return width_; }
int PlacementHead::getGap() { return gap_; }
// Palauttaa indeksissä i olevan suuttimen
char PlacementHead::getNozzle(int i) {
return set_[i-1];
}
// Asettaa indeksissä i olevan suuttimen
void PlacementHead::setNozzle(int i, char c) {
set_[i-1] = c;
}
// Merkitsee suuttimen poimituksi poistamalla sen listasta
void PlacementHead::markNozzle(int i, int bankPos) {
set_[i-1] = ' ';
from_[i-1] = bankPos;
}
// Palauttaa seuraavan poimimattoman suuttimen indeksin
int PlacementHead::getNextUnmarkedPos() {
for (int i=0; i<size_; i++) {
if (set_[i]!=' ') {
return i+1;
}
}
return 0;
}
// Palauttaa suuttimen alkuperäisen sijainnin pankissa
int PlacementHead::getBankPos(int i) {
return from_[i-1];
}
// Plauttaa alkuperäisen ladontapaan suutinjärjestyksen
void PlacementHead::reset() {
//for (int i=0; i<size_; i++) {
// set_[i] = original_[i];
//}
strcpy(set_,original_);
}
// Tulostusmetodi
void PlacementHead::print() {
std::cout << "ladontapaa:\n";
for (int h=height_; h>0; h--) {
for (int w=width_; w>0; w--) {
int i = ((h-1)*width_)+w;
std::cout << getNozzle(i);
}
std::cout << "\n";
}
}
PlacementHead.h:
#ifndef PLACEMENTHEAD_H
#define PLACEMENTHEAD_H
class PlacementHead {
public:
PlacementHead(int size, int rows, int gap, char* s);
~PlacementHead();
int getSize();
int getHeight();
int getWidth();
int getGap();
char getNozzle(int i);
void setNozzle(int i, char c);
void markNozzle(int i, int bankPos);
int getNextUnmarkedPos();
int getBankPos(int i);
void reset();
void print();
private:
char* set_;
int* from_;
char* original_;
int size_;
int width_;
int height_;
int gap_;
};
#endif
I notice that there is dynamic allocation of memory, but I don't see a delete anywhere...is this a problem? How could I fix this if it is a problem?
Thnx for any help!
P.S.
I noticed there is no keyword class used in this example?...Can you define a class like this?
It's impossible to say without seeing the class definition (the
header); if size_, etc. are something like
boost::shared_array, or std::unique_ptr, there is no leak.
If they are simply int*, there is a leak.
Of course, no C++ programmer would write this sort of code
anyway. The class would contain std::vector<int> and
std::string. Judging from what we see here, the author
doesn't know C++.
the code has leak . the constructor allocates the memory .Destructor or some other function have to clean that before the object gets destroyed
Another problem is that your code does not obey Rule of three (links here and here)
once you will write code like:
{
PlacementHead a(0,0,0,"asdsa");
PlacementHead b(0,0,0,"asdsa");
a = b; // line 1
} // here segfault
you will get segfault, in line 1, pointers will be copied from b to a, and once you will finally have destructors, pointers will be deleted twice, which is wrong. This is called shallow copy, you need deep copy, where new array will be allocated.