c++ swapping content of array - Selection Sort - c++

I'm new to C++. I was attempting to write a function for selection sort the following way.
void selection_sort(int* m[], int array_size) {
for (int i = 0; i < array_size; i++)
int min_ind = i;
for (int j = i+1; j < array_size; j++){
if (m[min_ind] > m[j]){
min_ind = j;
}
}
int temp = *m[i];
*m[i] = *m[min_ind];
*m[min_ind] = temp;
}
}
Within main, the array is defined as:
int *sel_nums = new int[n];
And I'm calling selection sort in main:
selection_sort( &sel_nums, x );
I keep getting an error that says:
Segmentation fault (core dumped)
Does anyone have any input on why this keeps happening?

You allocated dynamically an array of objects of the type int.
int *sel_nums = new int[n];
This array you are going to pass to the function selection_sort. So the function declaration will look at ;east like
void selection_sort( int m[], int array_size );
The compiler implicitly adjust the parameter having the array type to pointer to the array element type. That is the above declaration is equivalent to
void selection_sort( int *m, int array_size );
So the function can be called like
selection_sort( sel_nums, n );
To swap two elements of the array within the function you can write
if ( min_ind != i )
{
int temp = m[i];
m[i] = m[min_ind];
m[min_ind] = temp;
}
Or you could use the standard C++ function std::swap like
#include <utility>
//...
if ( min_ind != i )
{
std::swap( m[i], m[min_ind] );
}

Related

Invoking function with paremeters, one of which is an array of structures in C++?

I have a program where I have a function that sorts elements of an array of structures by their key field. However, when I invoke the function Insertion(a[],7) - I pass the array and its size, the compiler gives an error expected primary expression before ']' token. I would like to ask what am I doing wrong?
#include <iostream>
using namespace std;
struct CElem
{
int key;
};
CElem a[7];
void Insertion(CElem m[],int n)
{
CElem x;
int i;
int j;
for (i = 0; i < n; i++)
{
x = m[i];
j = i-1;
while (j >= 0 && x.key < m[j].key)
m[j+1] = m[j--];
m[j+1] = x;
}
}
int main()
{
a[0].key=32;
a[1].key=45;
a[2].key=128;
a[3].key=4;
a[4].key=-9;
a[5].key=77;
a[6].key=-7;
Insertion(a[],7);
return 0;
}
you only need to pass the pointer to the start of the array:
Insertion(a, 7);
Your parameter m of the method Insertion is of type CElem*. The variable a is of type CElem* too so you are supposed to give the method just a, like Insertion(a,7);.

Why does an array of pointers initializes itself when function finishes?

My weekend assignment was to make a function that gets an array of integers and the size of the array, and creates an array of pointers so that the pointers will be sorted using bubble sort (without changing the original array).
While debugging I found out that it works just fine, but when the function goes back to main() the pointers array gets initialized and everything's gone.
#include <iostream>
using namespace std;
void pointerSort(int arr[], int size, int* pointers[]);
void swap(int a, int b);
void main()
{
int arr[5]={7,2,5,9,4};
int size = 5;
int* pointers[5];
pointerSort(arr, size, pointers);
for (int i = 0; i < 5 ; i++)
cout << *pointers[i] << endl;
}
void pointerSort(int arr[], int size, int* pointers[])
{
int j, i;
bool change = true;
pointers = new int*[size];
for (i = 0; i < size; i++)
pointers[i] = &arr[i];
i = 0;
j = 1;
while (i <= size-1 && change == true)
{
change = false;
for (i = 0; i < size-j; i++)
{
if (*pointers[i] > *pointers[i+1])
{
swap(pointers[i], pointers[i+1]);
change = true;
}
}
j++;
}
}
void swap(int&a, int&b)
{
int temp;
temp = a;
a = b;
b = temp;
}
pointers = new int*[size];
At this point pointers is already an array of pointers, no allocation is needed.
After this line pointers IS NO LONGER THE ARRAY IN YOUR MAIN FUNCTION.
This is why your function is failing, because you are reassigning the array to which pointers is pointing to. The original array ISNT getting reinitialized, its just ignored throughout the entire code.
It is also a memory leak as ATaylor mentions, since you do not delete the allocated space, and cannot delete the space after the function finishes.
To fix everything: just remove the above line.

c++ using "indexing" over a 2D matrix, under this structure

don't know why but i get an error: after this structure i can't index the matrix, so i cant use the "indexing method" over the defined matrix.Can anyone tell me why? or how to fix it?
Header:
const int days=31;
const int exp=6;
struct Array{
int days;
int exp;
int **M;
};
Constuctor:
void constr(Array loc){
//Construct of 31*6 Matrix, were 31 nr. of days and 6 specific types:
//0-HouseKeeping, 1-Food, 2-Transport, 3-Clothing, 4-TelNet, 5-others
loc.days = days;
loc.exp = exp;
loc.M = new int*[loc.days];
for(int i=0; i<loc.days;i++ ){
loc.M[i] = new int[loc.exp];
for (int j = 0; j< loc.exp; j++){
loc.M[i][j] = 0;
}
}
}
Controller.cpp
void add(int cant,int tip, Array M){
//Adds to current day the amount to a specific type
currDay();
M[currentDay][tip] += cant; ////////////error
}
void insert(int zi,int tip,int cant, Array M){
//Adds to current day the amount to a specific type
M[zi][tip] = cant; ///////////error
}
void removeDay(int day, Array M){
for(int i = 0; i<6; i++)
M[day][i] = 0; ///////////error
//zi and tip ~ day type... for easier read.
//i need to manage the expenses of a family in a month doesn't matter which
ERROR: error: no match for 'operator[]'
UI(where constructor is used):
int main(){
Array M;
constr(M);
printMenu();
return 0;
}
You're not accessing the member:
M.M[currentDay][tip]
instead of
M[currentDay][tip]
Or you could define operator [] for your struct:
struct Array{
int days;
int exp;
int **M;
int*& operator[] (int idx) { return M[idx]; }
};
You are trying to call operator[] on the type array. You need to get the pointer member first.
M.M[day][i];
That said: You are not writing C++ but some obscure form of bad C. You might want to have a look at the book list and read one of them before pursuing coding any further.
You have at least two problems:
The first is that you are using the actual structure as the array, which wont work. Use e.g. M.M[day][i].
The second is that when you create the array, you pass the structure by value, this means it will be copied to a local variable in the constr function and the data will not be available in the function calling constr. Pass it as a reference instead, i.e. void constr(Array &loc).
The second problem can also be solved by using a constructor in the structure, instead of a separate function:
const int DAYS=31;
const int EXP=6;
struct Array{
int days;
int exp;
int **M;
// Constructor, called when an instance of structure/class is created
Array(){
days = DAYS;
exp = EXP;
M = new int*[days];
for(int i=0; i<days;i++ ){
M[i] = new int[exp];
for (int j = 0; j< exp; j++){
M[i][j] = 0;
}
}
}
// Destructor, called when structure/class is destroyed
~Array(){
if(M){
for(int i=0;i<days;i++){
if(M[i])
delete [] M[i];
}
delete [] M
}
}
// Copy constructor, called when instance of structure/class is copied
Array(const Array &array){
days = array.days;
exp = array.exp;
M = new int*[days];
for(int i=0; i<days;i++ ){
M[i] = new int[exp];
for (int j = 0; j< exp; j++){
M[i][j] = array.M[i][j];
}
}
}
};

Deleting a doublepointer (matrix)

I am solving a quantum-mech problem which requires me to find some eigenvalues by manipulating some matrices. The specifics of this problem is not relevant, I just need help with the c++ problem, I am new to this language and after a couple of hours I figured any more attempts at solving it myself would be futile and so I turn to you for help.
I have this problem where glibc detects an error at the end of my program and I cannot deallocate properly, it is far too big to copypaste here so I will just replicate the part that actually gives the error.
void hamiltonian(int, double **&);
int i,j;
int main()
{
int N = 1000; double **A;
hamiltonian(N, A);
//Physics here
.
.
.
.
.
//Delete
for(i=0; i<N; i++){delete []A[i];}
delete []A;
return 0;
}
void hamiltonian(int N, double **&A)
{
A = new double *[N];
for(i=0; i<N; i++)
{
A[i] = new double[N];
for(j=0; j<N; j++)
{
if(i==j)A[i][j] = 2;
if(i==j+1 || i==j-1){A[i][j] = 1;}
}
}
}
According to my professor I have to deallocate in the same function as I allocate but I didn't even think about deallocation after being nearly done with my project and so I have to rewrite a lot of code, the problem is that I cannot deallocate A inside the hamiltonian function as I need it in other functions (inside //Physics).
Surely there must be a way around this? Might sound a bit ignorant of me but this sounds like a less efficient design if I have to deallocate in the same function as I allocate.
According to my professor I have to deallocate in the same function as I allocate
That is pure silliness. Sometimes (almost always) you need to use the allocated struct outside the function. Definitely false for objects, since constructors and destructors are different functions.
Any way, you can get away without using classes, if you make a Matrix struct and associated newMatrix and deleteMatrix functions :)
#include <cstddef>
#include <iostream>
using namespace std;
struct Matrix
{
int n;
int m;
double** v;
};
Matrix newMatrix (int n, int m)
{
Matrix A;
A.n = n;
A.m = m;
A.v = new double*[n];
for( int i = 0; i < n; i++ ){
A.v[i] = new double[m];
}
return A;
}
Matrix newHamiltonianMatrix (int n, int m)
{
Matrix A = newMatrix(n, m);
for( int i = 0; i < A.n; i++ ){
for( int j = 0; j < A.m; j++ ){
A.v[i][j] = 0.0;
if( i == j ){
A.v[i][j] = 2.0;
}
if( i == j + 1 or i == j - 1 ){
A.v[i][j] = 1.0;
}
}
}
return A;
}
void deleteMatrix (Matrix A)
{
for( int i = 0; i < A.n; i++ ){
delete [] A.v[i];
}
delete [] A.v;
A.v = NULL;
}
int main ()
{
Matrix A = newHamiltonianMatrix(10, 20);
for( int i = 0; i < A.n; i++ ){
for( int j = 0; j < A.m; j++ ){
cout << A.v[i][j] << " ";
}
cout << endl;
}
deleteMatrix(A);
}
delete A;
Needs to be
delete[] A;
If you new[] it, you MUST delete[] it. Also, use a vector- they take care of themselves.
vector<vector<double>> matrix;
There are couple of problems with your code.
(1) You are not allocating memory to the pointer members of A. i.e. A[i] are not allocated with new[]. So accessing them is an undefined behavior.
(2) You must do delete[] for a pointer if it was allocated with new[]. In your other function delete A; is wrong. Use delete[] A;
(3) Using new/new[] is not the only way of allocation. In fact you should use such dynamic allocation when there is no choice left. From your code it seems that you are hard coding N=1000. So it's better to use an 2D array.
const int N = 1000; // globally visible
int main ()
{
double A[N][N];
...
}
void hamiltonian (double (&A)[N][N])
{
...
}

Delaying array size in class definition in C++?

Is there some way to delay defining the size of an array until a class method or constructor?
What I'm thinking of might look something like this, which (of course) doesn't work:
class Test
{
private:
int _array[][];
public:
Test::Test(int width, int height);
};
Test::Test(int width, int height)
{
_array[width][height];
}
What Daniel is talking about is that you will need to allocate memory for your array dynamically when your Test (width, height) method is called.
You would declare your two dimensional like this (assuming array of integers):
int ** _array;
And then in your Test method you would need to first allocate the array of pointers, and then for each pointer allocate an array of integers:
_array = new *int [height];
for (int i = 0; i < height; i++)
{
_array [i] = new int[width];
}
And then when the object is released you will need to explicit delete the memory you allocated.
for (int i = 0; i < height; i++)
{
delete [] _array[i];
_array [i] = NULL;
}
delete [] _array;
_array = NULL;
vector is your best friend
class Test
{
private:
vector<vector<int> > _array;
public:
Test(int width, int height) :
_array(width,vector<int>(height,0))
{
}
};
I think it is time for you to look up the new/delete operators.
Seeing as this is a multidimensional array, you're going to have to loop through calling 'new' as you go (and again not to forget: delete).
Although I am sure many will suggest to use a one-dimensional array with width*height elements.
(Months later) one can use templates, like this:
// array2.c
// http://www.boost.org/doc/libs/1_39_0/libs/multi_array/doc/user.html
// is professional, this just shows the principle
#include <assert.h>
template<int M, int N>
class Array2 {
public:
int a[M][N]; // vla, var-len array, on the stack -- works in gcc, C99, but not all
int* operator[] ( int j )
{
assert( 0 <= j && j < M );
return a[j];
}
};
int main( int argc, char* argv[] )
{
Array2<10, 20> a;
for( int j = 0; j < 10; j ++ )
for( int k = 0; k < 20; k ++ )
a[j][k] = 0;
int* failassert = a[10];
}