Need to find 3 small errors - memory bugs [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
As part of a college assignment, we were tasked with analyzing some code in an effort to identify memory issues. There's 3 we are to find. As I am quite new to the concept of pointers, I am drawing a blank. I do know main() should be returning an int and that the use of the "unsigned" means non-negative integers in this case.
Compiler Errors
Tried searching for similar problems.
void main()
{
double* d = new double;
for (unsigned int i = 0; i < 3; i++) {
d[i] = 1.5 + i;
}
for (unsigned int i = 2; i >= 0; i--) {
cout << d[i] << endl;
}
}
The program results in an infinite loop of memory addresses.

the first problem is the return type of the main function
the second one is in:
double* d = new double;
you are allocating memory for one double but in your loops, you are accessing to 3 indexes
and last
for (unsigned int i = 2; i >= 0; i--)
the unsigned type can't hold negative value and so after it gets to zero it going up again to max unsigned int (x^32)-1 and you again accessing out of range places
so your code should look like that:
#include <iostream>
int main()
{
double* d = new double[3];
for (unsigned int i = 0; i < 3; i++) {
d[i] = 1.5 + i;
}
for ( int i = 2; i >= 0; i--) {
std::cout << d[i] << std::endl;
}
delete[] d;
return 0;
}

In this statement you are creating memory in heap only for one double variable. If you need 3 . Then you must allocate memory for 3 variable like.
double* d = new double[3];
And the reason loop is infinite is because in second loop when value of i will go to -1 since the variable is unsigned it will get converted to very large positive number depending on your machine like in my machine
it get converted to 4294967295.
unsigned int i = -1;
cout<<i; //try running this code and you will see value of i to be 4294967295
Error explanation
See your 3rd and 2nd last error say the same that value is converted to very large int.
Other error said as i explained above that you have allocated memory for 1 double ie 8byte but you are using it for 3 double (d[1],d[3],d[3]) which is 8 x 3 = 24 bytes.
Remaining is return type which must be int not void

Related

C++ "new" operator not working as expected [duplicate]

This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
How do I find the length of an array?
(30 answers)
Closed 2 years ago.
int main()
{
int *array = new int; //Should provide space to store only one integer right?
for(int i =0; i < 10; i++)
{
cout << "Assigning" << i << "th value\n";
array[i] = i + 1;
}
for(int i = 0; i < 10; i++)
cout << array[i] << '\t';
delete array;
cout << '\n';
return 0;
}
Output
Assigning0th value
Assigning1th value
Assigning2th value
Assigning3th value
Assigning4th value
Assigning5th value
Assigning6th value
Assigning7th value
Assigning8th value
Assigning9th value
1 2 3 4 5 6 7 8 154274097 154405171
I know pointer size on my system is 8 bytes, checked with sizeof(int*) and integers take 4 bytes. I want to know how many chunks of memory in heap or free store (like literally boxes they use to teach students) does int* array = new int created, because books say I can store just one integer in it; to store more(like 10 ints) I need to do int* array = new int[10]. So how does this memory location pointed to by array can store 8 integers instead of one. Please note, I ran for loop 10 times as shown. Please tell me why are there just 2 garbage values, instead of 9 (since new should only allocate one integer worth space). Using Ubuntu with g++ 9.3.0.
int *array = new int; //Should provide space to store only one integer right?
Allocates a single int not an array.
for(int i =0; i < 10; i++)
{
cout << "Assigning" << i << "th value\n";
array[i] = i + 1;
}
Since there is no array but only a single element any access beyond the first (array[0]) array elements causes undefined behavior.
Any action, even formatting your hard drive, would be a valid program behavior.
Edit:
adapted to nearly completely rewritten question

In this Fibonacci function which works, doesn't it pass the number of elements that can be stored in the array? [duplicate]

This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 3 years ago.
This is my code and it works. For example, when n=5, it returns 5. Since n=5, and defining arr[0] = 0, isn't there only four more spaces left to store the elements from arr[1] to arr[4]?
However, it seems like 6 elements(from arr[0] to arr[5]) could be stored and I do not know how.
int fibonacci(int n) {
int i;
int arr[n];
arr[0] = 0;
for(i=1; i<=n; i++)
{
if(i==1)
{
arr[i] = 1;
}
else
{
arr[i] = arr[i-2] + arr[i-1];
}
}
return arr[n];
}
This is undefined behaviour.
Behind the scenes
What's going on behind the scenes is that 5 ints are allocated on the stack. Lets say they're put at address 0x20 to 0x30. The array notation [] is really syntax sugar for using pointers. This means that arr[0] really is a pointer to 0x20. Your array in this case translates to the following addresses (because sizeof(int) = 4):
arr[0] = (arr+0) = 0x20
arr[1] = (arr+1) = 0x24
arr[2] = (arr+2) = 0x28
arr[3] = (arr+3) = 0x2C
arr[4] = (arr+4) = 0x30
This is all fine and good, you're operating on allocated memory. What happens when you try to write to index 5? Well, the same thing, basically:
arr[5]= (arr+5) = 0x34.
It's still just a pointer to an address that you want to write to. The problem is, however, that you haven't told anyone that you intend to write to that address - the memory has not been set aside for you.
If it has not been set aside for anything else, this will likely turn out alright - as you observe.
However if it has it can turn into all sorts of strange behavior depending on what it was used for. Maybe it has been set aside and is just not used yet, maybe it has been used but is simply overwritten and will not be checked again. The point is we don't know! Therefore it is dangerous and undefined.
The reason why it even works in the first place, is that - again - it is just dereferencing a pointer. And dereferencing a pointer should work, as you're trusted to know more that the compiler. It may warn you that you probably shouldn't do this, but it's not an error per se.
What you should do instead
When working with variable length arrays in C++, one should use the modern tools available since C++11. In this scenario, it's advisable to use std::vector instead. If you use the at function rather than [] it checks whether the index is inside the bounds.
Its unexpected behavior, even warn by C++ documents, maybe they removed out-boundary checking. Not only that, you even assign to it. So better to be under range.
#include <iostream>
using namespace std;
int main(){
int i, n = 5;
int arr[n];
arr[0] = 0;
arr[1] = 1;
for(i=2; i<n; i++){
arr[i] = arr[i-2] + arr[i-1];
}
arr[8]=99; //assigning out of range
//accessing out of range
for(i=0;i<20;i++){
cout<<arr[i]<<" ";
}
}
#OUT: 0 1 1 2 3 0 211951624 1 99 32766 -484579280 32766 -1740650656 32767 -484579408 32766 5 0 5 0
You are facing issues with the int array. int arr[n]; is not valid C++ code if n is not fix at compile time. You can rewrite your code with the help of std::vector as
int fibonacci(int n) {
std::vector<int> arr(n);
arr[0] = 0;
for(int i=1; i<=n; i++)
{
if(i==1)
{
arr[i] = 1;
}
else
{
arr[i] = arr[i-2] + arr[i-1];
}
}
return arr[n];
}
Comments:
Your code will use a lot of memory for large Fibonacci numbers, since you store the entire series. This is superfluous, since only have to store the last two entries of the Fibonacci series.
You don't have to loop over n in order to calculate the Fibonacci number. The Moivre-Binet formula gives a much quicker way of calculating these.
for(i=1; i<=n; i++)
the for loop wil run if i is less than or equal to n, which means that when n = 5, it will still run.

C++ unable to index an element of an array using a nested loop [duplicate]

This question already has answers here:
Split an Integer into its digits c++
(12 answers)
Closed 3 years ago.
I am having difficulty understanding how i can fix this this error "array1[i][j] = expression must be a pointer-to-object type. I have searched the error but i am unable to apply the solutions to my code snippet.
int main(){
int array1[]= {1234,4321}; //{1234,4321};
int array2[]= {2345,3214}; //{2345,3214};
int counter = 0;
int arr_element = sizeof(array1);
int arr_index = sizeof(array1)/sizeof(*array1);
for(int i = 0, count1 = arr_index; i < count1; i++ ){
for(int j = 0, count2 = 4; j < count2; j++){
cout << array1[i][j] << endl;
}
}
return 0;
}
What i would like to do is be able to print out the elements in array1; for example, i would like this output: 1,2,3,4,4,3,2,1. From my understanding, the int a needs to be a pointer. I i added * in front of the array (*array1) and in front of the int (int**), but with no luck. Thank you for your time.
Ypu are using one dimensional array, What you are wishing for is a 2dimensional array and that's how you declare it
int array1[][]= {{1,2,3,4},{4,3,2,1}};
int array2[][]= {{2,3,4,5},{3,2,1,4}};

Segmentation fault error while trying to expand array with realloc in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
My code works well and gives right results up to 3 iterations. However, I got a segmentation fault error after 3 iterations when I trying to run code below:
int addNode(double* distNewNode,int placeCount, int* phi,double* lambda)
{
int i ;
int nextPlaceCount = placeCount+1;
//int nodeCount = placeCount -1;
phi= realloc(phi,nextPlaceCount*sizeof(int));
lambda = realloc(lambda,nextPlaceCount*sizeof(double)); //This line throws the error
phi[placeCount] = placeCount;
lambda[placeCount] = DBL_MAX;
for (i = 0;i < placeCount; i++)
if (lambda[i] >= distNewNode[i])
{
if (lambda[i] <= distNewNode[phi[i]])
distNewNode[phi[i]] = lambda[i];
lambda[i] = distNewNode[i];
phi[i] = placeCount;
}
else if (distNewNode[i] < distNewNode[phi[i]])
distNewNode[phi[i]] = distNewNode[i];
for (i = 0;i < placeCount;i++)
if(lambda[i] >= lambda[phi[i]] )
phi[i] = placeCount;
return 1;
}
Here is how I called the addNode() function:
int main()
{
//Create distMat here
int* phi;
phi = (int*)malloc(1);
phi[0] = 1;
//phi[1] = 1;
double* lambda;
lambda = (double*)malloc(1);
//lambda[0] = 1.2;
lambda[0] = DBL_MAX;
int isNodeAdded;
for (int placeCount=0; placeCount < 10;placeCount++)
{
double* temp =(double*) malloc(placeCount);
for (int j= 0;j < placeCount ;j++)
{
temp[j] = distMat[placeCount][j];
}
isNodeAdded = addNode(temp,placeCount,phi,lambda);
cout << "isNodeAdded: "<<isNodeAdded << endl;
free(temp);
for (int i=0;i < placeCount ;i++)
{
printf("Node= %d Pi = %d Lambda = %f \n",i,phi[i],lambda[i]);
}
}
}
My output is:
isNodeAdded: 1
isNodeAdded: 1
Node= 0 Pi = 1 Lambda = 1.200000
isNodeAdded: 1
Node= 0 Pi = 1 Lambda = 1.200000
Node= 1 Pi = 2 Lambda = 3.400000
isNodeAdded: 1
The program has unexpectedly finished.
The problem is that you pass the argument phi by value, which means its value is copied into the function local variable phi, and as with all local variable phi goes out of scope when the function returns and all changes to it inside the function is lost.
If the function addNode is in a C source file, then you can't pass by reference since it's not supported by C, so you have to emulate it by passing a pointer to the pointer variable, i.e. in the main function you need to pass &phi, and have the function modified to take int **phi instead, with proper dereferencing of the variable as needed.
If, on the other hand, the addNode is in a C++ source file, then you can just change the argument to int *&phi and you will have a reference variable, which will reference the original variable passed as the argument from the main function.
You also have another problem which will give you undefined behavior in the main function:
phi = (int*)malloc(1);
phi[0] = 1;
Here you allocate one byte, and use it as an int which it typically four bytes.
On an unrelated note, you should not reassign the result of realloc back to the variable you passed as argument. Think about what happens if realloc returns NULL. The original pointer is still valid, but if you reassign it you will lose the pointer and thereby have a memory leak.

Data type clash [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
#include <iostream>
#include <iomanip>
using namespace std;
void reverseOrder (double []);
int main() {
const int size = 4;
double array[size] = {1.2, 6.7, -12.45, 34.9};
cout << "Forwards:" << " " << endl;
for (int index = 0; index < size; index++) {
cout << array[index] << endl;
}
// Display in reversed order.
cout << "Backwards: " << endl;
reverseOrder(array[size]);
return 0;
}
void reverseOrder(double array[]) {
const int size = 10;
int j;
double reverseOrder[size];
double temp = 0;
for (int i = 0, j = size - 1; i < (size / 2); i++, j--) {
temp = reverseOrder[i];
reverseOrder[i] = array[j];
reverseOrder[j] = temp;
}
for (int reverse = 0; reverse < size; reverse++) {
cout << array[reverse] << endl;
}
}
error C2664: 'void reverseOrder(double [])' : cannot convert argument 1 from 'double' to 'double []'
error is here ---> reverseOrder(array[size]);
You are calling your function reverseOrder(double[]) with array[size] as argument which is only one element of the array(*). So you are passing a double but the function expects an array.
In your case you should call the function with reverseOrder(array).
(*)in this case it is not even an element because it points to the element after the last one because the first element is accessed by 0 and so by 4 you would actually access the 5th element (thanks to drescherjm for pointing that out)
Your particular problem (just the first one from what we can observe) is that you are trying to pass a single double to a function expecting the array of doubles. It is because
array[index]
returns a value of the array associated with given index (you should call this like reverseOrder(array);). That is, it returns this as long as the index is in the allowed range. This is not the case here, because array[size] is one past the last element of the array. The last one is indexed array[size-1]. Thus you are experiencing undefined behavior.