Unexpected Result Each Time - c++

I have been trying to implement the Fibonacci series in linear time. I keep getting weird results each time I run the program. I am a newbie in C++.
int fib1(int n) {
int arr[n];
arr[0] = 0;
arr[1] = 1;
for (int i = 2; i < n; i++) {
arr[i] = arr[i - 1] + arr[i - 2];
}
return arr[n];
}
int main() {
int x = fib1(3);
cout << x << endl;
return 0;
}
The expected result is: 2
The result I am getting is: 4199748
Where did I mess up?

If arr is of length n it doesn't have an element with index n and therefore you are accessing the array out-of-bounds in return arr[n]. That causes undefined behavior and anything could happen. You probably wanted an array of length n+1 and iteration up to i <= n.
Furthermore the array size must be known at compile time in standard C++. Therefore the variable-length array arr[n] is only allowed because your compiler has special support for it. Use std::vector instead.

Related

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.

Pointer Indexing: Getting Unexpected Values

#include <iostream>
using namespace std;
int* computeSquares(int& n)
{
int arr[10];
n = 10;
for (int k = 0; k < n; k++)
arr[k] = (k + 1) * (k + 1);
return arr;
}
void f()
{
int junk[100];
for (int k = 0; k < 100; k++)'
junk[k] = 123400000 + k;
}
int main()
{
int m;
int* ptr = computeSquares(m);
f();
for (int i = 0; i < m; i++) {
cout << ptr[i] << ' ';
}
}
The above code should print:
1 4 9 16 25 36 49 64 81 100
However, it instead prints random integer values that don't make any sense, at least after the first one. After running the code through the debugger, the ptr address is deleted right after the first run of the for loop in the main method and I cannot fathom why. Additionally, I have no idea what the purpose of the f() method is, I don't think it should change anything but when I remove it from the main the first value returns accurately (everything after is still wrong.) What is going on?
Try this:
int *computeSquares(int &n) {
int *arr = new int[10];
n = 10;
for (int k = 0; k < n; k++)
arr[k] = (k + 1) * (k + 1);
return arr;
}
The memory of "int arr[10]" is released after computeSquares finished running.
You are getting this result because you are misunderstanding basic language features. In addition to MsrButterfly's answer, who pointed out the most important problem already, let me please give you the following advices:
forget about using raw pointers; it is dangerous practice, very hard to maintain and extend, and will for sure lead you to write code with memory leaks. You will be better off having a look at some STL documentation which possesses e.g. the std::vector container that you could use instead of your array arr
your computeSquares method is dangerous in the sense that you take a variable n a argument which should be your array's size. In your method, you first define arr with a hard-coded size of 10 and then you set n = 10; I'd suggest you avoid that kind of constructs as you have in this case to maintain two variables that depend on that number 10.

Initialize two 2-d array to zero in C/C++

My question is can we initialize 2-d array using int a[10][10] = {{0}}.
According to the top answer in initialize-large-two-dimensional-array-in-c,
int array [ROW][COLUMN] = {0};
which means: "initialize the very first column in the first row to 0, and all other items as if they had static storage duration, ie set them to zero."
However, checking C99 Standard 9899:TC3 and C++11 Standard N4296, I haven't found any official records supporting what was mentioned in this answer.
Besides, I do come across this issue when I try to solve the LeetCode 474. Ones and Zeroes problem with the following solution.
// To make question clear:
// It seems that "int dp[m + 1][n + 1] = {{0}}" cannot initilize all elem to 0
// "memset(dp, 0, sizeof dp)" is necessary to pass the OJ test. Any idea?
class Solution {
public:
// m : 0s, n : 1s
int findMaxForm(vector<string>& strs, int m, int n) {
int dp[m + 1][n + 1] = {{0}};
// We will get "Wrong Answer" without memset() function below
memset(dp, 0, sizeof dp);
for (auto& str : strs) {
auto cost = getCost(str);
for (int i = 0; i + cost.first <= m; ++i)
for (int j = 0; j + cost.second <= n; ++j)
dp[i][j] = std::max(dp[i + cost.first][j + cost.second] + 1,
dp[i][j]);
}
int max = 0;
for (int i = 0; i <= m; ++i)
for (int j = 0; j <= n; ++j)
max = std::max(max, dp[i][j]);
return max;
}
private:
pair<int, int> getCost(const string& str) const {
int cnts[] = {0, 0};
for (char c : str) ++cnts[static_cast<char>(c == '1')];
return {cnts[0], cnts[1]};
}
};
Your code is C++ code. Other questions and documents about C are irrelevant; C and C++ are different languages.
In Standard C++ , array dimensions must be known at compile-time. int dp[m + 1][n + 1] is an error (let alone trying to initialize it).
Possibly you're using a compiler that offers C++ VLA as a non-standard extension. In that case you are at the mercy of the particular compiler as to what the behaviour of the code will be, and what the behaviour of ={{0}} on it might be. The C++ standard will not help.
My advice would be to avoid non-standard constructs, so that you retain the guarantees provided by the standards documents.

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[]/

my function always returns a huge number

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.