my function always returns a huge number - c++

Now my function works better, but it did't return the minimum number, it returns the second largest... Could anyone help me? I can't find the error.
#include <iostream>
#include <cstdio>
#include <cstdlib>
void add_min(int*& a, int n){
int c;
for(int i = 0; i < n - 1; i++){
if(a[i + 1] < a[i]){
c = a[i + 1];
}
else{
c = a[i];
}
}
std::cout<< c <<std::endl;
for(int s = 0; s < n; s++){
a[s] += c;
}
for(int z = 0;z < n; z++){
std::cout<< a[z] <<std::endl;
}
}
int main(){
int n,i;
std::cout<< "please enter the dimention of the array" <<std::endl;
std::cin>> n;
int *arr = new int[n-1];
std::cout<< "please enter the integers in the array" <<std::endl;
for(i = 0;i < n; i++){
std::cin>>arr[i];
}
add_min(arr, n);
delete [] arr;
return 0;
}

Problem 1 :
int c, a[n];
b = a[n];
size of a = n , therefore you can at maximum access a[n-1] , not a[n] since index starts from 0 , not 1 in c .
Problem 2 :
have you initialized the values of array a ?
when arrays are initialized in functions , they are filled with random values .

Besides the problem mentioned in my comment, the problem is that you're using an uninitialized local array, which means it will contain seemingly random data. You also start out by reading a value out of bounds with b = a[n];
I think what you really meant to do was to pass in the complete array as an argument, instead of creating new in the function.

These huge numbers you are talking about are the definition of undefined output. Why are you getting this?
In your loop, you're doing:
if(a[i + 1] < a[i])
But remember that arrays are zero-based in C++, so you're getting out of bounds in the last iteration, because i + 1 will be n, and the array's size is n-1 (Indexes run in the range [0, n-1]).
Tip: Debugging your code can save your time (and your life), use the debugger!
Furthermore, more important issue, you're using an uninitialized array that initially contains garbage values.

Related

Garbage value when trying to remove value from dynamic array

i keep getting garbage value on one of the indexes in the dynamic array when i try to remove a value which was entered by user from a list of elements in the dynamic array.
used pointer as function parameters and replaced the value to be removed with 0 and by using a counter and for loop tried to skip all the 0s but in place of zero theres a garbage value.
#include<iostream>
#include<fstream>
using namespace std;
int size = 0;
int final = 0;
int* read(ifstream& a){
int temp;
a.open("data(1).txt");
while (!a.eof()){
a >> temp;
size++;
}
a.close();
a.open("data(1).txt");
int* arr = new int[size];
for (int i = 0; i < size; i++)
a >> arr[i];
return arr;
}
int* remove(int* a,int search){
for (int i = 0; i < size; i++){
if (a[i] == search)
a[i] = 0;
else final++;
}
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
delete[] a;
a = nullptr;
return change;
}
int main(){
int* ptr = nullptr;
int num;
cout << "please enter the number to remove: ";
cin >> num;
ifstream in;
ptr=read(in);
ptr=remove(ptr, num);
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
cout<<endl;
system("pause");
return 0;
}
There is much to discuss and critize about your code. Also your question is very unclear because we do not have your input file, nor do you tell us what the code should actually do. However, I will leave all "please write actual c++ rather than c without classes" aside and just point you to the one critical mistake:
This loop
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
And then this loop
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
It seems like you want to copy all elements that are >0 to change. Or maybe you want to copy all, its really hard to tell, because broken code is just broken, it does not explain itself. Anyhow...
The first loop leaves all elements change[i] where a[i] <= 0 uninitialized. The values at those indices i are indeterminate. There isn't really a value you can read. Attempting to read an indeterminate value results in undefined behavior.
You are attempting to read all elements of change, but some of them are not initialized, they are indeterminate values. Hence your code has undefined behavior.
There are other situations the will bring your code into bad states, like for example search not begin found in the input array or a[i] > 0 for some i > final. Though, I don't see a possiblity for any input to your code that would not eventually invoke undefined behavior.
You sould use a debugger to see where your code is doing something unexpected.

Deleting elemnt from array and calculating sum

Number can't be in array if it can be divided by number of elements of array (for example: in array which has 10 elements, numbers 1,2,5 and 10 are not "welcome"). So I need to find all these elements in array and kick them out. After that length of array changes, and then some other elements can be "not welcome" in array. I have to repeat it until array is without these elements. In the end, I have to calculate remaining elements and print them out. (I'm using C++)
I didn't know how to delete element from array, and just set value to 0.
I get input n (number of elements in array) and then all of these elements.
So, I already tried it but I'm sure there is much more effective way to do it :P Here is the code:
int main()
{
short int b = 0;
short int n;
int result = 0;
cin >> n;
int m = n;
int numbers[n];
for (int i = 0; i < n; i++) {
cin >> numbers[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j<=n; j++) {
if(numbers[j] != 0) {
if(n % numbers[j] == 0) {
numbers[j] = 0;
b = b + 1;
} }
}
n = n - b;
b = 0;
}
for (int i = 0; i < m; i++) {
result += numbers[i];
}
cout << result;
return 0;
}
example input: 10 1 2 3 4 5 6 7 8 9 10
example output: 24
I didn't know how to delete element from array
It is not possible to "delete element from array". An array of n elements begins its life with n elements, has n elements throughout its entire lifetime, and ends its life with n elements. It is not possible to change the size of an array.
Another problem:
cin >> n;
int numbers[n];
The size of an array must be a compile time constant. n is not a compile time constant. This is not a well-formed C++ program.
An array of runtime size must be allocated dynamically. The easiest solution is to use std::vector. The size of a vector can change, and you can use std::vector::erase to remove elements from it.

I'm trying to sort an array by counting the elements and then sort them again "counting sort"

I'm trying to sort the array by making another array with size of the maximum number in the array I want to sort, then each time I find the number I ++ the index of that number..ex: the main array is {5,3,8,1,2,3}
the other array {0,1,1,2,0,1,0,0,1}
then my sorted array will be like {1,2,3,3,5,8} I have no idea why my code is not working any help please?
#include <iostream>
using namespace std;
int findmax(int a[], int size){
int max = a[0];
for (int i = 0; i < size; i++)
if (max < a[i])
max = a[i];
return max;
}
void sort(int a[], int n){
int max = findmax(a, n);
int *arr;
arr = new int[max+1];
for (int i = 0; i < n; i++){
arr[a[i]]++;
}
for (int k = 0; k < n;){
for (int l = 0; l <= max; l++) {
while (arr[l] != 0){
a[k] = l;
arr[l]--;
k++;
}
}
}
What you really should be doing is to step through the code line by line in a debugger. That way you will easily see what the problem is.
But since I started writing this I might as well post it as an answer.
The problem is that the array you allocate and assign to arr is not initialized, its contents is indeterminate. And using uninitialized data is undefined behavior.
What's really is happening is that the data you allocate will be seemingly random, and most likely none of it will be zero. That leads to your counts being all wrong.
The solution is to clear the memory you allocate before counting values:
std::fill(arr, arr + max + 1, 0);

Function behaves badly when passing dynamically allocated pointer

I have this function
void shuffle_array(int* array, const int size){
/* given an array of size size, this is going to randomly
* attribute a number from 0 to size-1 to each of the
* array's elements; the numbers don't repeat */
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
r = mt_lrand() % size; // my RNG function
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
array[i] = r;
else
i--;
}
}
When I call this function from
int array[FIXED_SIZE];
shuffle_array(array, FIXED_SIZE);
everything goes all right and I can check the shuffling was according to expected, in a reasonable amount of time -- after all, it's not that big of an array (< 1000 elements).
However, when I call the function from
int *array = new int[dynamic_size];
shuffle_array(array, dynamic_size);
[...]
delete array;
the function loops forever for no apparent reason. I have checked it with debugging tools, and I can't say tell where the failure would be (in part due to my algorithm's reliance on random numbers).
The thing is, it doesn't work... I have tried passing the array as int*& array, I have tried using std::vector<int>&, I have tried to use random_shuffle (but the result for the big project didn't please me).
Why does this behavior happen, and what can I do to solve it?
Your issue is that array is uninitialized in your first example. If you are using Visual Studio debug mode, Each entry in array will be set to all 0xCC (for "created"). This is masking your actual problem (see below).
When you use new int[dynamic_size] the array is initialized to zeros. This then causes your actual bug.
Your actual bug is that you are trying to add a new item only when your array doesn't already contain that item and you are looking through the entire array each time, however if your last element of your array is a valid value already (like 0), your loop will never terminate as it always finds 0 in the array and has already used up all of the other numbers.
To fix this, change your algorithm to only look at the values that you have put in to the array (i.e. up to i).
Change
for(j = 0; j < size; j++)
to
for(j = 0; j < i; j++)
I am going to guess that the problem lies with the way the array is initialized and the line:
r = mt_lrand() % size; // my RNG function
If the dynamically allocated array has been initialized to 0 for some reason, your code will always get stack when filling up the last number of the array.
I can think of the following two ways to overcome that:
You make sure that you initialize array with numbers greater than or equal to size.
int *array = new int[dynamic_size];
for ( int i = 0; i < dynnamic_size; ++i )
array[i] = size;
shuffle_array(array, dynamic_size);
You can allows the random numbers to be between 1 and size instead of between 0 and size-1 in the loop. As a second step, you can subtract 1 from each element of the array.
void shuffle_array(int* array, const int size){
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
// Make r to be betwen 1 and size
r = rand() % size + 1;
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
{
array[i] = r;
}
else
i--;
}
// Now decrement the elements of array by 1.
for(i = 0; i < size; i++){
--array[i];
// Debugging output
std::cout << "array[" << i << "] = " << array[i] << std::endl;
}
}
You are mixing C code with C++ memory allocation routines of new and delete. Instead stick to pure C and use malloc/free directly.
int *array = malloc(dynamic_size * sizeof(int));
shuffle_array(array, dynamic_size);
[...]
free(array);
On a side note, if you are allocating an array using the new[] operator in C++, use the equivalent delete[] operator to properly free up the memory. Read more here - http://www.cplusplus.com/reference/new/operator%20new[]/

Passing integers to arrays within functions (without pointers)

I'm trying to create a magic square that will print four different grid sizes (5x5, 7x7, 9x9, 15x15). The error I'm having is the array magsquare within the function tells me it needs a constant integer. (I can't use pointers) This is a class assignment.
#include <iostream>
#include <iomanip>
using namespace std;
void magicSquare(int n){
int magsquare[n][n] = { 0 }; /*THIS is the error with [n][n]*/
int gridsize = n * n;
int row = 0;
int col = n / 2;
for (int i = 1; i <= gridsize; ++i)
{
magsquare[row][col] = i;
row--;
col++;
if (i%n == 0)
{
row += 2;
--col;
}
else
{
if (col == n)
col -= n;
else if (row < 0)
row += n;
}
}
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
cout << setw(3) << right << magsquare[i][j];
}
cout << endl;
}
}
int main(){
int n = 5;
magicSquare(n);
return 0;
}
Indentation may look incorrect, but it's right. Sorry.
The failure is because standard C++ cannot allocate dynamically sized array on the stack, as you are trying to do.
int magsquare[n][n];
As far as magicSquare is concerned n is only known at runtime and for an array to be allocated on the stack it's size must be known at compile time.
Use a 15 x 15 array.
int magsquare[15][15];
As long as you know this is the largest you'll ever need, you should be ok.
Alternatives (which you've already said you can't use)
Use new to declare a 2d array of the required dimensions. (Remember to delete[] it though)
Use std::vector
It may also be a good idea to add a check that n values over 15 or under 1 are rejected, otherwise you'll face undefined behaviour if any values outside of 1-15 are passed into the function.