Problems on sorting an array in my function - c++

I'm trying to write a function which sort an array and I met a problem. When I sort an array it always return 0 in first position of sorted array. No matter what combination it is.
void sorting(int wielkosc)
{
int t[wielkosc];
//filling
for (int i = 0; i < wielkosc; i++)
{
t[i] = rand()% 100 + 1;
}
// before sort
cout << "before sorting: " << endl;
for (int i = 0; i < wielkosc; i++)
{
cout << "[" << i << "] -> " << t[i] << endl;
}
cout << endl;
// asc...
int iTemp = 0;
for (int i = 0; i < wielkosc; i++)
{
for (int j = i + 1; j <= wielkosc; j++)
{
//jak chcesz zmienic na malejaco to se przekrec '<' na '>'
if (t[j] < t[i])
{
iTemp = t[i];
t[i] = t[j];
t[j] = iTemp;
}}}
// after sorting
cout << "after sorting: " << endl;
for (int i = 0; i < wielkosc; i++)
{
cout << "[" << i << "] -> " << t[i] << endl;
}
cout << endl;
}

Related

Implementation of dynamic arrays

In my assignment, I am to find a sum grid using dynamic arrays. Here is my code without the use of dynamic arrays (I used a 2d array). I made the size dependent on user input. Can someone help me understand and implement dynamic arrays in this code? If you need, I can post all of my code to help you understand what I am trying to do.
void sumGrid(int array[], int& Size)
{
cout << "Sum Grid" << endl;
int a2d[Size][Size];
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
a2d[i][j] = array[i] + array[j];
}
}
cout << " " << setw(7);
for (int j = 0; j < Size; j++)
{
cout << setw(7) << array[j] << ' ';
}
cout << endl;
for ( int k = 0; k < Size; k++)
{
cout << array[k] << ' ';
for (int l = 0; l < Size; l++)
{
cout << setw(7) << a2d[k][l] << ' ';
}
cout << endl;
}
cout << endl;
}
The output of my code looks like:
Sum Grid
1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
The statement int a2d[Size][Size]; is defining a Variable-Length Array, since Size is not a compile-time constant. VLAs are not part of standard C++, so they should be avoided. The correct and standard way to allocate a dynamic array is to use the new[] operator (see 1, 2), eg:
void sumGrid(int array[], int& Size)
{
cout << "Sum Grid" << endl;
int **a2d = new int*[Size];
for (int i = 0; i < Size; i++)
{
a2d[i] = new int[Size];
for (int j = 0; j < Size; j++)
{
a2d[i][j] = array[i] + array[j];
}
}
cout << " " << setw(7);
for (int j = 0; j < Size; j++)
{
cout << setw(7) << array[j] << ' ';
}
cout << endl;
for ( int k = 0; k < Size; k++)
{
cout << array[k] << ' ';
for (int l = 0; l < Size; l++)
{
cout << setw(7) << a2d[k][l] << ' ';
}
cout << endl;
}
cout << endl;
for (int i = 0; i < Size; i++)
{
delete[] a2d[i];
}
delete[] a2d;
}
Alternatively, using a 1d array that mimics a 2d array, so that the entire array is allocated sequentially in memory and not scattered around memory:
void sumGrid(int array[], int& Size)
{
cout << "Sum Grid" << endl;
int *a2d = new int[Size*Size];
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
a2d[(i*Size)+j] = array[i] + array[j];
}
}
cout << " " << setw(7);
for (int j = 0; j < Size; j++)
{
cout << setw(7) << array[j] << ' ';
}
cout << endl;
for ( int k = 0; k < Size; k++)
{
cout << array[k] << ' ';
for (int l = 0; l < Size; l++)
{
cout << setw(7) << a2d[(k*Size)+l] << ' ';
}
cout << endl;
}
cout << endl;
delete[] a2d;
}
That being said, you should avoid using new[]/delete[] directly, as it is error-prone, and particularly risks leaking memory if an error occurs. Use the standard std::vector container instead, let it handle the memory management for you, eg:
Using a 2d sparse array:
#include <vector>
void sumGrid(int array[], int& Size)
{
cout << "Sum Grid" << endl;
std::vector<std::vector<int>> a2d(Size);
for (int i = 0; i < Size; i++)
{
a2d[i].resize(Size);
for (int j = 0; j < Size; j++)
{
a2d[i][j] = array[i] + array[j];
}
}
cout << " " << setw(7);
for (int j = 0; j < Size; j++)
{
cout << setw(7) << array[j] << ' ';
}
cout << endl;
for ( int k = 0; k < Size; k++)
{
cout << array[k] << ' ';
for (int l = 0; l < Size; l++)
{
cout << setw(7) << a2d[k][l] << ' ';
}
cout << endl;
}
cout << endl;
}
Using a 1d sequential array:
#include <vector>
void sumGrid(int array[], int& Size)
{
cout << "Sum Grid" << endl;
std::vector<int> a2d(Size * Size);
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
a2d[(i*Size)+j] = array[i] + array[j];
}
}
cout << " " << setw(7);
for (int j = 0; j < Size; j++)
{
cout << setw(7) << array[j] << ' ';
}
cout << endl;
for ( int k = 0; k < Size; k++)
{
cout << array[k] << ' ';
for (int l = 0; l < Size; l++)
{
cout << setw(7) << a2d[(k*Size)+l] << ' ';
}
cout << endl;
}
cout << endl;
}

Can you explain what run time error is how to fix it

void adde(int& v, char array[5])
{
if (v > 5) {
v = -1;
}
for (int k = 0; k < 5; k++) {
if (array[k] == 'C') {
array[k] = '-';
}
}
v++;
array[v] = 'C';
}
this is my function
int mov = -1;
char item[5];
for (int i = 0; i < 5; i++) {
item[i] = '-';
}
cout << "Initially " << endl;
for (int i = 0; i < 5; i++) {
cout << "[" << i + 1 << " ] ";
}
cout << endl;
for (int j = 0; j < 5; j++) {
cout << item[j] << " ";
}
cout << endl;
cout << "After Item 1, " << endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
cout << item[j] << " ";
}
cout << endl;
cout << "After Item 2, " << endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
cout << item[j] << " ";
}
cout << endl;
cout << "After Item 3, " << endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
cout << item[j] << " ";
}
cout << endl;
cout << "After Item 4, " << endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
cout << item[j] << " ";
}
cout << endl;
cout << "After Item 5, " << endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
cout << item[j] << " ";
}
cout << endl;
My code works fine till here.
After the last item i want my cursor to point back to first index
but shows weird Library Run time error
After it runs this highlighted part of code
cout << "After Item 6, " << endl;
adde(mov, item);
for (int j = 0; j < 5; j++) { cout << item[j] << " "; } }
Heading ##You did a simple mistake. No need for a debbugger here. Arrays in C/C++ start with index 0. So if you have an array of size 5, like in your example char item[5];, the valid indices are 0,1,2,3,4. But not 5.
In your function adde you simply have the wrong boundary check. In your very first statement you have written:
if (v > 5) {
then later
v++;
array[v] = 'C';
So, if v is >3, for example 4 or 5, you will increment it and access array[5] or array[6], which is out of bounds and produces an error.
You may simply correct it and use
if (v > 3) {
as you first statement. This will fix the problem:
#include <iostream>
void adde(int& v, char array[5])
{
if (v > 3) {
v = -1;
}
for (int k = 0; k < 5; k++) {
if (array[k] == 'C') {
array[k] = '-';
}
}
v++;
array[v] = 'C';
}
int main() {
int mov = -1;
char item[5];
for (int i = 0; i < 5; i++) {
item[i] = '-';
}
std::cout << "Initially " << std::endl;
for (int i = 0; i < 5; i++) {
std::cout << "[" << i + 1 << " ] ";
}
std::cout << std::endl;
for (int j = 0; j < 5; j++) {
std::cout << item[j] << " ";
}
std::cout << std::endl;
std::cout << "After Item 1, " << std::endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
std::cout << item[j] << " ";
}
std::cout << std::endl;
std::cout << "After Item 2, " << std::endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
std::cout << item[j] << " ";
}
std::cout << std::endl;
std::cout << "After Item 3, " << std::endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
std::cout << item[j] << " ";
}
std::cout << std::endl;
std::cout << "After Item 4, " << std::endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
std::cout << item[j] << " ";
}
std::cout << std::endl;
std::cout << "After Item 5, " << std::endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
std::cout << item[j] << " ";
}
std::cout << std::endl;
std::cout << "After Item 6, " << std::endl;
adde(mov, item);
for (int j = 0; j < 5; j++) {
std::cout << item[j] << " ";
}
std::cout << std::endl;
return 0;
}
Please additionally note:
The design is not very good. Please do not use C-style arrays in C++. Please avoid pointer decays in calls to functions. Please rethink you complete design. I can see, what you are doing. This can be done easier in C++, but for a really good or approriate solution, we need to know the requriements.

Limiting the inputs and again asking the user for the right range

I'm stuck on this program: I have to limit the input but the program just totally ignore the if statement if i enter a value greater or equal to 100 it should
display an error but continue to ask user for input and run
Here is my code:
#include<iostream>
using namespace std;
int main()
{
int a[4][4], big1, n, m, i, j, loc1, loc2;
cout << "Enter no of rows and columns:";
cin >> m >> n;
cout << "Enter the array:\n";
if (n > 100 || m>100 )
{
cout << "Error! number should in range of (1 to 99)." << endl;
cout << "Enter the number again: ";
cin >> m >> n;
}
else
for (i = 0; i < m; i++)
{
for (j = 0; j < n; ++j)
{
cin >> a[i][j];
}
}
cout << endl << "Entered Matrix: " << endl;
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
{
cout << " " << a[i][j];
if (j == n - 1)
cout << endl << endl;
}
big1 = a[0][0];
loc1 = 0;
loc2 = 0;
for (i = 0; i < m; ++i)
{
for (j = 0; j<n; ++j)
{
for (int i = 0; i<4; i++)
for (int j = 0; j<4; j++)
if (a[i][j]>big1)
{
big1 = a[i][j];
loc1 = i;
loc2 = j;
}
}
}
cout << "\nLargest number:" << big1 << endl;
cout << "The position that had the largest number is in " << " Row " << loc1 << " " << "Column " << loc2 << endl;
system("pause");
return 0;
}
I've added a while to repeat the check until the number falls below 100. Please note the line "int a[4][4],.." will overrun if you exceed 4 rows * 4 columns. I suggest moving its initialization to a lower position when rows and columns are known.
Try this :
#include<iostream>
using namespace std;
int main()
{
int big1, n, m, i, j, loc1, loc2;
cout << "Enter no of rows and columns:";
cin >> m >> n;
cout << "Enter the array:\n";
while (n > 100 || m>100 )
{
cout << "Error! number should in range of (1 to 99)." << endl;
cout << "Enter the number again: ";
cin >> m >> n;
}
int a[m][n];
//else redundant
for (i = 0; i < m; i++)
{
for (j = 0; j < n; ++j)
{
cin >> a[i][j];
}
}
cout << endl << "Entered Matrix: " << endl;
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
{
cout << " " << a[i][j];
if (j == n - 1)
cout << endl << endl;
}
big1 = a[0][0];
loc1 = 0;
loc2 = 0;
for (i = 0; i < m; ++i)
{
for (j = 0; j<n; ++j)
{
for (int i = 0; i<4; i++)
for (int j = 0; j<4; j++)
if (a[i][j]>big1)
{
big1 = a[i][j];
loc1 = i;
loc2 = j;
}
}
}
cout << "\nLargest number:" << big1 << endl;
cout << "The position that had the largest number is in " << " Row " << loc1 << " " << "Column " << loc2 << endl;
system("pause");
return 0;
}

C++ losing vector elements after .size()

I'm a C++ novice and my problem is that I somehow (seemingly) lose vector elements just by calling .size(). For the following code segment (full code attached below) I get the following output:
A: number of elements: 560
B: number of elements: 560
B: number of elements: 0
B: number of elements: 0
B: number of elements: 0
C: number of elements: 0
//SEGMENT IN QUESTION
cout << "A: number of elements: " << combinations.size() << endl;
float sum_vect[120][2];
for (int i = 0; i < combinations.size(); ++i) {
for (int j = 0; j < 2; ++j) {
sum_vect[i][j] = 0;
}
}
cout << "B: number of elements: " << combinations.size() << endl;
cout << "B: number of elements: " << combinations.size() << endl;
cout << "B: number of elements: " << combinations.size() << endl;
cout << "B: number of elements: " << combinations.size() << endl;
for (int i = 0; i < combinations.size(); ++i) {
combination = combinations.at(i);
for (int j = 0; j < order; ++j) {
sum_vect[i][0] += (float)virtual_pos[combination[j]][0];
sum_vect[i][1] += (float)virtual_pos[combination[j]][1];
}
}
vector<int> optimal_ind;
cout << "C: number of elements: " << combinations.size() << endl;
//AUXILIARY FUNCTIONS
void nchoosek_helper(int offset, int n, int k, vector<vector<int>> &combinations, vector<int> combination) {
if (k == 0) {
combinations.push_back(combination);
return;
}
for (int i = offset; i <= n - k; ++i) {
combination.push_back(i);
nchoosek_helper(i+1, n, k-1, combinations, combination);
combination.pop_back();
}
}
double euclidean_norm(double dist1, double dist2){
return sqrt(pow(dist1,2) + pow(dist2,2));
}
//FUNCTION IN QUESTION STARTS HERE
//weirdest: look at A B C
vector<vector<char> > step37::CUDADriver::get_access_pattern(int order){
vector<vector<char> > result;
vector<vector<int> > combinations;
vector<int> combination;
nchoosek_helper(0, 16 ,order, combinations, combination);
cout << "number of combinations: " << combination.size() << endl;
// //mapping lexical index 1-16 to 2D array
int virtual_pos [16][2];
for (int i = 0; i < 16; ++i) {
virtual_pos[i][0] = i%4 * order; //write x
virtual_pos[i][1] = (int)ceil(i/4) * order; //write y
cout << "mapping " << i << "to (" << i%4 * order << "'" << (int)ceil(i/4) * order<< ")" << endl;
}
cout << "A: number of elements: " << combinations.size() << endl;
float sum_vect[120][2];
for (int i = 0; i < combinations.size(); ++i) {
for (int j = 0; j < 2; ++j) {
sum_vect[i][j] = 0;
}
}
cout << "B: number of elements: " << combinations.size() << endl;
cout << "B: number of elements: " << combinations.size() << endl;
cout << "B: number of elements: " << combinations.size() << endl;
cout << "B: number of elements: " << combinations.size() << endl;
for (int i = 0; i < combinations.size(); ++i) {
combination = combinations.at(i);
for (int j = 0; j < order; ++j) {
sum_vect[i][0] += (float)virtual_pos[combination[j]][0];
sum_vect[i][1] += (float)virtual_pos[combination[j]][1];
}
}
vector<int> optimal_ind;
cout << "C: number of elements: " << combinations.size() << endl;
cout << "main loop"<< endl;
for (int i = order; i < order*2; ++i) {
for (int j = order; j < order*2; ++j) {
int pos [2];
// pos[0] = i;
// pos[1] = j;
pos[0] = j;
pos[1] = i;
cout << "current position: (" << j << "," << i << ")" << endl;
float min_len = std::numeric_limits<float>::infinity(); //minimum length of combined vector
float min_sum_ind = std::numeric_limits<float>::infinity(); //minimum sum of individual vectors
int min_idx = -1;
for (int k = 0; k < combinations.size(); ++k) {
int curr_vect [2];
curr_vect[0] = sum_vect[k][0] - pos[0] * order;
curr_vect[1] = sum_vect[k][1] - pos[1] * order;
float curr_len = euclidean_norm(curr_vect[0], curr_vect[1]);
float min_sum_tmp = 0;
combination = combinations[k];
for (int l = 0; l < order; ++l) {
min_sum_tmp += euclidean_norm(virtual_pos[combination.at(l)][0] - pos[0],
virtual_pos[combination.at(l)][1]- pos[1]);
}
if (i==4&&j==4){
cout << " ind sum: " << min_sum_tmp << " len: " << curr_len << " sv: (" << sum_vect[k][0] << "," << sum_vect[k][1] <<
") cv: (" << curr_vect[0] << "," << curr_vect[1] << ")" <<endl;
}
if (min_len > curr_len ||
min_len == curr_len && min_sum_tmp < min_sum_ind){
min_len = curr_len;
min_idx = k;
min_sum_ind = min_sum_tmp;
}
}
// cout <<
cout << "pushing minimal idx " << min_idx << endl;
optimal_ind.push_back(min_idx);
}
}
cout << "main loop done"<< endl;
//unpack optimal combinations into relative movements
vector<char> optimal_x((int)pow(order,3));
vector<char> optimal_y((int)pow(order,3));
cout << "number of elements: " << combinations.size() << endl;
for (int i = 0; i <(int)pow(order,2); ++i) {
cout << "optimal idx: " << optimal_ind.at(i) << endl;
combination = combinations.at(optimal_ind.at(i));
for (int j = 0; j < order; ++j) {
int lex_idx = combination.at(j); //some index between 0 and 15 from 4x4 grid
//mvt range in grid relative to thread position: -1 to +
int relative_x = -1 + lex_idx % 4;
int relative_y = -1 + (int) floor(lex_idx / 4);
optimal_x[i * order + j] = relative_x;
optimal_y[i * order + j] = relative_y;
}
}
//DEBUG print
for (int i = 0; i < (int)pow(order,2); ++i) {
combination = combinations.at(optimal_ind.at(i));
cout << "combination: " << i << " ";
for (int j = 0; j < order; ++j) {
cout << combination.at(j) << " ";
}
cout << endl;
}
result.push_back(optimal_x);
result.push_back(optimal_y);
for (int i = 0; i < optimal_x.size(); ++i) {
cout << (int)optimal_x.at(i) << " " << endl;
}
cout << "optimal sizes: " << optimal_x.size() << endl;
cout << "optimal sizes: " << optimal_y.size() << endl;
cout << "result size: " << result.size() << endl;
return result;
}
I really don't understand how it's possible for a function like .size() to change the vector object (or maybe it just happens coincidentally at the same time). The application runs in single thread but I guess it wouldn't matter anyways given that everything relevant should be contained within the scope of the function. Obviously, the code stops working at a later point when I actually try to access some elements of combinations (std::out_of_range). I guess I must be missing out on something very basic given the gravity of the error. What's disturbing is that everything works just fine if I use 2 as an argument to get_access_pattern(). Everything above (tested with 3 and 4) results in this error.
You have a buffer overrun. Your output:
A: number of elements: 560
Your code:
cout << "A: number of elements: " << combinations.size() << endl;
float sum_vect[120][2];
for (int i = 0; i < combinations.size(); ++i) {
for (int j = 0; j < 2; ++j) {
sum_vect[i][j] = 0;
}
}
Look at the "i" variable when it gets to 120 in that loop. You are accessing sum_vect[120][j], which is out-of-bounds.
When a buffer overrun occurs, your program then will exhibit undefined behavior.

system("pause") not working, can anyone see what I'm missing?

My program has errors and wont let me compile. The only errors start at system("pause) though but I dont see why I'm having errors because I did it the same as I always do my programs. Can anyone see what might be the issue? heres the code:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
//Declarations
int SIZE = 10;
int NUMBERS[10];
int i;
int j;
int temp;
for (int i = 0; i < SIZE; i++)
{
cout << "Please enter a number: " << endl;
cin >> NUMBERS[i];
}
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
if (NUMBERS[j] > NUMBERS[j+1])
{
temp = NUMBERS[j];
NUMBERS[j] = NUMBERS[j+1];
NUMBERS[j+1] = temp;
}
}
}
cout << "Sorted List" << endl;
cout << "===========" << endl;
for (int i = 0; i < SIZE; i++)
cout << "Number " << i + 1 << ": " << NUMBERS[i] << endl;
}
system("pause");
return 0;
}
for (int i = 0; i < SIZE; i++) {
// ^^^ add this missing bracket
cout << "Number " << i + 1 << ": " << NUMBERS[i] << endl;
}
^^^ // closing bracket, but has no opening match
Of course you can skip braces in this case ( as there is only one single line in for body) so this is also solution:
for (int i = 0; i < SIZE; i++)
cout << "Number " << i + 1 << ": " << NUMBERS[i] << endl;