Is there anything wrong with the usage of the "return" values of the three fuction? The values printed out are garbage values with seemingly random numbers as outputs.I would also like to add that i havent made it recursive because i wanted to check whether this would work or not.
Most all of the mergesort implementation I've seen hardly contain any return values, is that something im doing wrong. If you were to go about a similar type of implementation, how would you do it?
#include <iostream>
using namespace std;
int* goleft(int array[], int size)
{
int halved=size/2;
int left[halved];
for(int i=0;i<halved;i++)
{
left[i]=array[i];
}
return left;
}
int* goright(int array[],int size)
{
int halved=size/2;
int right[size-halved];
for(int i=halved,j=0;i<size;i++,j++)
{
right[j]=array[i];
}
return right;
}
int* mergesort(int array[],int size)
{
int *l,*r;
l=goleft(array,size);
r=goright(array,size);
int merger[size];
int halved = size/2;
int i;
for(i=0;i<halved;i++)
cout<<l[i]<<endl;
for(i=0;i<halved;i++)
cout<<r[i]<<endl;
int x=0,y=0,k=0;
while(x+y!=size)
{
if(l[x]<r[y])
{
merger[k]=l[x];
x++;k++;
}
else if(l[x]>=r[y])
{
merger[k]=r[y];
y++;k++;
}
}
return merger;
}
int main()
{
int size;
cin>>size;
int array[size];
for(int i=0;i<size;i++)
cin>>array[i];
int *merged=mergesort(array,size);
cout<<"sorted array"<<endl;
for(int i=0;i<size;i++)
cout<<merged[i]<<endl;
return 0;
}
And when we create variables of same name during loops and recursions, are new variable created for every loop iteration or recursion? or do they overwrite the value for the previous variable. for e.g when we write
while(true)
{
int i=0;
}
would a new variable be made at every iteration
and
genericFunction()
{
int i = SomeRandomValue
genericFunction();
}
similarly would a new variable be made at each recursion?
As you thought, the error is in "scopes". To answer to your questions :
while(true)
{
int i=0;
}
The process is :
//iteration N start
create scope
allocate memory for an int variable named 'i' in the current scope
//statements done
delete current scope //deallocate the variables in the current scope
//iteration N end
//iteration N+1 start
/*...*/
So in each iteration it is a different variable. You can test it with this code :
while (true) {
int i;
std::cout << &i << std::endl; //displays the memory location of i
system("PAUSE"); //waiting user input between each iteration
}
In the example with genericfunction, the process is :
//N call to genericFunction
create scope //scope N
//N+1 call to generic Function
create scope //scope N+1
/* statements */
delete current scope //scope N+1
// exit of call N+1
delete current scope //scope N
//exit of call N
You can test it with this complete code :
#include <iostream>
void genericFunction(int a)
{
int i = 0;
std::cout << "scope " << a << " : " << &i << std::endl;
if (a < 9) { //to prevent infinite call
genericFunction(a + 1);
}
std::cout << "scope " << a << " : " << &i << std::endl;
}
int main() {
genericFunction(0);
system("PAUSE");
return 0;
}
A generic rule is : when you have {, you create a new scope and select it as current scope, when you have }, you delete the current scope and select the previous scope. Some scopes permits access to previous scopes (for example a WHILE LOOP : in the code int a; while(true) {a++;}, it modifies the value of a in the previous scope), but when a function scope is created you have no access to previous scopes.
Now for your specific issue with mergedsort, it is the declaration of your variable merger inside the function mergesort. To see the process :
/* ... */
int *merged=mergesort(array,size);
//Call to mergesort
//Creation of scope A
/* ... */
int merger[size]; //Allocation of memory for 'merger' in scope A
/* ... */
return merger; //Affect the location of 'merger' to location pointed by 'merged' in previous scope
//Deletion of scope A (including deallocation of 'merger')
// Now 'merged' points to location of 'merger' which is a deallocated variable :
//no guarantees of the data stored at this location
So it is why there is a problem in your code. One way to correct it is by allocate manually some space for your variable : variables allocated manually have to be deallocated manually, so they will not be deallocated when destroying a scope. Actually the implementation inside the function is using the c++ keyword new : int *merger = new int[size];.
By replacing this declaration your code will be running : but be careful : here's an other rule, if you're using somewhere the keyword new you have to use delete somewhere else : manual allocation have to be followed by manual deallocation. So at the end of your main function, you have to add delete[] merged;. In this way there's no trouble ;) .
Related
While learning the dynamic object creation in C++ i have encountered a doubt . Here is my code.
And my question is , when the limiting condition in the loop is same as that of the no of objects created it works fine. But what happens when the loop works for more than the size given , it seems printing the values entered , but we have created only 4 objects and changed the condition of loop to more than 4
#include <iostream>
using namespace std;
class item{
int number;
public:
item(){
cout<<"Constructor"<<endl;
}
~item(){
cout<<"Destructor"<<endl;
}
void get_num(int num){
number = num
};
void show_num(){
cout<<"Number is "<<number<<endl;
}
};
const int size=4;
int main() {
item *itemObj = new item[size];
item *d = itemObj; //copy the address of itemObj inorder to access its member functions later
int tempNum;
for (int i = 0; i < size; ++i) {
cout<<"Enter the Number"<<endl;
cin>>tempNum;
itemObj->get_num(tempNum);
itemObj++;
}
//to print the numbers entered
for (int i = 0; i < size; ++i) {
d->show_data();
d++;
cout<<d<<endl;
}
delete itemObj;
return 0;
}
Your code isn't working fine at all. Because you change the value of the pointer that you requested from the new operator. When you call the delete for the itemObj at the last line, it doesn't have its original value.
So, instead of modifying the itemObj, you should modify the copy of it which is the pointer d here. Therefore, the problem isn't about the iteration amount of the loop. It's actually the violation on the heap memory.
Also, if you're creating a dynamic array, you should call delete [] instead of delete.
From my knowledge after a function is called in c++ its memory is deallocated for another variables. If it doesn't allocates to another variable then variable should have allocated memory dynamically. I'm confused how the function display() displays array values when it isn't allocated memory dynamically.
#include<iostream>
using namespace std;
void init_values(int arr[]){
for(int i=0;i<100;i++){
arr[i]=i;
}
}
void display(int arr[]){
for(int i=0;i<100;i++){
cout<<arr[i] << " ";
}
}
int main(){
int arr[100];
init_values(arr);
display(arr);
}
I expected the function displays garbage or will show an error. But it displayed the values correctly.
void init_values(int arr[]){
for(int i=0;i<100;i++){ // i is created here
arr[i]=i;
} // i goes out of scope here
}
No problems here, there's no attempt to use i later.
void display(int arr[]){
for(int i=0;i<100;i++){ // i is created here
cout<<arr[i] << " ";
} // i goes out of scope here
Again, no problem.
int main(){
int arr[100]; // arr is created here
init_values(arr);
display(arr);
} // arr goes out of scope here
When we call init_values and display, arr is still in scope since its lifetime ends at the end of the scope it was created in. So it's still in scope during those function calls.
Now, this would be a problem:
int *init_values(void){
int arr[100];
for(int i=0;i<100;i++){
arr[i]=i;
}
return arr;
}
Why? Think about it:
int *init_values(void){
int arr[100]; // arr is created here
for(int i=0;i<100;i++){
arr[i]=i;
}
return arr;
} // arr goes out of scope here
So the caller of init_values would receive a pointer to arr's contents even though arr does not exist after we exit this function. This function's return value could not be safely used. Your code doesn't do this.
I am a newbie for OOP concepts and while trying to solve Project Euler Problem 7, to find 10001th prime number, I tried to do it using a class but encountered 2 major errors.
instantiating the class prime_n
initializing its argument
I have posted the code here for reference:
#include<iostream>
#include<cstdio>
using namespace std;
class prime_n
{
int j,k;
int n;
int *store;
public:
prime_n(int num)
{
n=num;
store[n];
}
static int isPrime(int j)
{
for(int i=2;i*i<=j;i++)
{
if(j%i==0) return 0;
}
return 1;
}
void find_n()
{
for(int i=0;i<n;i++)
{
store[i]=0;
}
store[0]=2;
j=3;
k=1;
while(store[n-1]==0)
{
if(isPrime(j)) store[k++]=j;
j+=2;
}
}
int get_num()
{
int value=store[n-1];
return value;
}
};
int main()
{
int num, req_num;
printf("Enter the position at which prime number is to be found ");
scanf("%d",&num);
printf("\nnumber = %d",num);
prime_n p = new prime_n(num);
req_num = p.get_num();
printf("The required prime number is %d\n",req_num);
return 0;
}
It would be a great help if someone could help me figure out where I am actually going wrong. Thanks a lot in advance!
Use
prime_n p(num);
or (not recommended in this particular case)
prime_n * p = new prime_n(num);
// some other code
req_num = p->get_num(); // note the -> operator replacing . in case of pointers
delete p;
The first case declares p on stack and it is automatically deallocated when the program leaves the scope (main function in this case)
The second one allocates space on heap and p is the pointer to it. You have to deallocate the memory manually.
As for your second question, the C++ way would be
#include <iostream>
...
int num;
std::cout << "Enter the position at which prime number is to be found "
std::cin >> num;
std::cout << std::endl << "Number = " << num << std::endl;
You provide a constructor:
prime_n(int num)
{
n=num;
store[n];
}
I think you are under the impression that store[n] creates an array with n elements, but that is not so; it attempts to access the (n+1)th element of an an array. Since store does not point anywhere (we are in the constructor, after all), the program crashes.
You probably want to write store = new int[num] instead.
And then I cannot see any call to find_n() originating from get_num() which is called in main(), so that your program would for now just return a random value.
I am trying to send a array of 15 integers between two functions in C++. The first enables the user to enter taxi IDs and the second functions allows the user to delete taxi IDs from the array. However I am having an issue sending the array between the functions.
void startShift ()
{
int array [15]; //array of 15 declared
for (int i = 0; i < 15; i++)
{
cout << "Please enter the taxis ID: ";
cin >> array[i]; //user enters taxi IDs
if (array[i] == 0)
break;
}
cout << "Enter 0 to return to main menu: ";
cin >> goBack;
cout << "\n";
if (goBack == 0)
update();
}
void endShift ()
{
//need the array to be sent to here
cout << "Enter 0 to return to main menu: ";
cin >> goBack;
cout << "\n";
if (goBack == 0)
update();
}
Any help is great valued. Many thanks.
Since the array has been created on the stack, you would just need to pass the pointer to the first element, as an int*
void endshift(int* arr)
{
int val = arr[1];
printf("val is %d", val);
}
int main(void)
{
int array[15];
array[1] = 5;
endshift(array);
}
Since the array is created on the stack, it will no longer exist once the routine in which it was created has exited.
Declare the array outside of those functions and pass it to them by reference.
void startShift(int (&shifts)[15]) {
// ...
}
void endShift(int (&shifts)[15]) {
// ...
}
int main() {
int array[15];
startShift(array);
endShift(array);
}
This isn't exactly pretty syntax or all that common. A much more likely way to write this is to pass a pointer to the array and its length.
void startShift(int* shifts, size_t len) {
// work with the pointer
}
int main() {
int array[15];
startShift(array, 15);
}
Idiomatic C++ would be different altogether and use iterators to abstract away from the container, but I suppose that is out of scope here. The example anyway:
template<typename Iterator>
void startShift(Iterator begin, Iterator end) {
// work with the iterators
}
int main() {
int array[15];
startShift(array, array + 15);
}
You also wouldn't use a raw array, but std::array.
It won't work to use a local array in the startShift() function. You are best off to do one or more of the following:
Use an array in the function calling startShift() and endShift() and pass the array to these functions, e.g.:
void startShift(int* array) { ... }
void endShift(int* array) { ... }
int main() {
int arrray[15];
// ...
startShift(array);
// ...
endShift(array);
// ...
}
Don't use built-in arrays in the first place: use std::vector<int> instead: that class automatically maintains the current size of the array. You can also return it from a function altough you are probably still best off to pass the objects to the function.
void endShift (int* arr)
{
arr[0] = 5;
}
It is being said that local variable will be allocated and deallocated automatically when function ends in C/C++.
According to my understanding, when having been deallocated, the value held by local variable also be destroyed!!! Please correct me if i'm wrong
Consider following code:
void doSomething(int** num)
{
int a = 10;
*num = &a;
} // end of function and a will be destroyed
void main()
{
int* number;
doSomething(&number);
cout << *number << endl; // print 10 ???
}
Could anybody clarify for me?
You are correct. your cout may or may NOT print 10. It will invoke undefined behavior.
To make a bit more of a note, try running the following code under your compiler with no optimizations enabled.
#include <iostream>
using namespace std;
void doSomething(int** num)
{
int a = 10;
*num = &a;
}
void doSomethingElse() {
int x = 20;
}
int main()
{
int* number;
doSomething(&number);
doSomethingElse();
cout << *number << endl; // This will probably print 20!
}
In this case, the integer a is on the stack. You are returning the address of that variable to the main program. The value at that address location after the call is undefined. It is possible in some situations that it could print 10 if that portion of the stack was not overwritten (but you certainly would not want to rely on it).
The content of the memory isn't actually destroyed.
For this case, num will point to a location which isn't being allocated for any variable, but it will hold it's content, which was set to 10.
The memory being pointed to has been released back to the system. That means that it will hold whatever value it had until the system assigns that block of memory to another variable and it gets overridden with a value.
Local variables are released when they go out of scope. If you are trying to return a value using an out parameter to a function:
void doSomething(int** num)
{
int* a = new int;
*a = 10;
*num = a;
}
int main()
{
int* number = 0;
doSomething(&number);
std::cout << *number << std::endl; // print 10 ???
if (number) delete number;
}
Though, for something this simple, you are better off just doing this:
int doSomething()
{
return 10;
}
int main()
{
std::cout << doSomething() << std::endl;
}