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
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;
}
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.
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;
}
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.
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;