C++: Insert an element in a Vector without insert() - c++

I have been trying to solve the above problem for a friend, everytime the last element of the vector gets removed although I feel that its size should increase dynamically after insertion.
Here's the Code:
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
void display(vector<int> arr){
cout<<"Result"<<endl;
for(auto &p: arr){
cout<<p<<endl;
}
}
void indsert(vector<int> arr, int size, int element, int ind){
for(int i=size+1; i>=ind; i--)
arr[i] = arr[i-1];
arr[ind] = element;
display(arr);
}
int main()
{
int ind,size,element;
cout<<"Enter the size of the array"<<endl;
cin>>size;
vector<int> arr;
cout<<"Enter the elements of the array"<<endl;
for(int i=0;i<size;i++){
int temp;
cin>> temp;
arr.push_back(temp);
}
cout<<"Enter the element to be inserted"<<endl;
cin>>element;
cout<<"Enter the index"<<endl;
cin>>ind;
indsert(arr, size, element, ind);
return 0;
}

You have two problems.
The first is with the function signature:
void indsert(vector<int> arr, ...)
You pass the vector by value. That means a copy of the vector is made, and that copy is passed to the function.
You can modify this copy as much as you want, but the original vector will still not change.
You need to pass the vector by reference:'
void indsert(vector<int>& arr, ...)
// ^
// Note ampersand here, making this a reference
The second problem is much worse: You seem to assume that you can insert into a vector using the [] operator. That's not what's happening.
Instead you go out of bounds of the vector, which leads to undefined behavior.
You need to explicitly resize the vector, either using insert, push_back/emplace_back, or resize.
Also remember that since indexes are zero-based, the top-index is the same as the vector size minus one. Using the vector size as index will be out of bounds. Using the vector size plus one is even more out of bounds.

Your code exhibits undefined behaviour. You are accessing arr[size+1] in a vector arr of size size. Such a vector has values at positions 0 up to and including size-1.
If you want to append a value, use std::vector::push_back(). Alternatively you can std::vector::resize() the vector beforehand.
Also, you don't need to pass the size argument because std::vector::size() will tell you the current size of the vector. Furthermore, as has been pointed out to you, pass the vector by reference to avoid copying data for no reason.

Related

implementation of stacks using vector - segmentation fault in peek() function

#include <iostream>
#include <vector>
using namespace std;
class Stack{
public:
vector<string> vc;
int length=0;
void peek(){
if(vc.size()==0){
cout<< "The stack is empty"<<endl;
}
cout<< vc[length]<<endl; //----> does not work;
//cout<<vc[vc.size()-1]; ---> does not work either
//cout<<vc.end(); ----> does not work either;
}
void add(string value){
vc.push_back(value);
length++;
}
void pop(){
vc.erase(vc.end());
length--;
}
void show(){
for (int i=0;i<vc.size();i++){
cout << vc[i] << " ";
}
cout<<endl;
}
};
int main()
{
Stack mystack;
mystack.peek();
mystack.add("Hello");
mystack.peek();
mystack.add("frands");
mystack.add("chai");
mystack.add("pee");
mystack.add("lo");
mystack.show();
mystack.peek();
mystack.pop();
mystack.show();
}
problem 1->
the problem arises in the peek() function i cannot access the last element in my vector space i get returned with a segmentation fault(core dump) error.
problem 2->
and while pasting this code on stack overflow i had to manually add 4spaces in each code line how to do this at one step (sorry for a silly question).
There are a few problems in your code:
void peek(){
if(vc.size()==0){
cout<< "The stack is empty"<<endl;
}
cout<< vc[length]<<endl; //----> does not work;
}
If vc.size() == 0, you print out a message, and then proceed to index into the empty vector. You should return inside that if, to avoid looking at an invalid index.
Below it you use use a length variable, which I presume is the acting the role of the vector's size(). EITHER you need to ensure the vector's size is the same as the stack's logical size (and then you don't need a length variable), OR you should be testing if length == 0, and not looking at size() here. Otherwise, you could have a positive size of vector, and a length of zero, and what's logically empty may print junk values.
Another serious mistake, your pop function:
void pop(){
vc.erase(vc.end()); // <<< MISTAKE
length--;
}
This is erasing the "end" element, which is not a valid position to erase. Remember, end denotes the first place after the last valid element in the vector, so your code yields undefined behavior. You should use the vector function pop_back instead, as it does precisely what you want. It also will reduce the size of the vector, meaning you don't need a length variable at all! Instead you can use the vector's size().
Next, in peek():
cout<< vc[length]<<endl;
When a vector contains N things, they are indexed from 0..(N-1). Using the number of elements will go too far into the vector. Instead, use length-1 (or vc.size()-1 after fixing pop()). However, you can use vc.back() to access the last element without any need to compute its offset.

Enter elements into dynamic (pointer-defined) array in C++?

I want to ask a question regarding entering elements in a dynamic array. I declare an array and then I want to enter elements in it. How can I do this using pointers into the array arr[] that I have declared previously?
Thanks in advance!
#include <iostream>
#include <algorithm>
using namespace std;
int *n = new int ;
int main()
{
cin>>*n;
int *arr = new int[*n];
int *i=new int;
for(*i=0; *i<=*n; *i++)
{
//Here, I should enter the elements but I cannot figure out how?
cin>>(*arr+i);
}
return 0;
}
While I question your usage of pointers for the size of the array and the index (They should just be int n; and int i = 0;, respectively), you can fix your code by using the subscript operator, or in code:
cin >> arr[*i];
Using pointer arithmetic is just unclear and makes it hard to tell what your goal is (In case you're wondering, the correct notation is *(arr+*i), which looks horrible IMO).
On a side note, consider using std::vector as a container, which will make your life a lot easier and prevent you from having to deal with pointers. Usage of std::vector may look like:
int main()
{
std::vector<int> arr;
for (int x; std::cin >> x;)
{
arr.push_back(x);
}
return 0;
}
This would prevent you from having to ask the user for the size of the std::vector as well and allow them to keep entering elements until they enter an EOF.
Here I am not changing your original approach at all so that you can understand pointer concept a bit more clear. As you know that array and pointer address calculation are exactly same. First you need to calculate the address and then dereference it. You just need to change it like below:-
cin>>*arr++;
Also you need to change your for loop like below:-
for(*i=0; *i<=*n; (*i)++)
But now after the above for loop you are going to face problem. The reason is that after storing each element in arr we have incremented the address of arr(arr++), so after the end of for loop arr is now pointing to the last element ( because arr = arr+*n). So first simply try with the below code:-
cout<<*arr<<endl<<endl;
if you have entered five numbers for example 0,1,2,3, and 4 the above statement will print some junk value as pointer is increment one more time.
now try with below:-
arr--;// Now arr will point to last element i.e. 4
cout<<*arr<<endl<<endl;
Hence you need one more int pointer and should store the first address of arr in it like below:-
int *arr = new int[*n];//exactly after this line of code
int *first = arr;
Now use a for loop to print the array:-
arr = first; //pointing to the first eliment
for(*i=0; *i<=*n; (*i)++)
{
//Here, I should enter the elements but I cannot figure out how?
cout<<*arr++<<endl;
}

Assign a pointer to an array

I am trying to create an array that generates random values, then assign a pointer to that array in order to use it in other functions.
Question 1: Is this the right approach?
Question 2: When I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
int size = 100;
int theray[size];
for(int i=0; i<size; i++)
{
theray[i] = (rand()%100);
}
//Output array
cout<<"The array: ";
for(int j=0; j<size; j++)
{
cout<<theray[j]<<" ";
}
cout<<endl;
int (*parray)[100] = &theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<*parray[k]<<" ";
}
Question 1: is this the right approach?
No. The right approach is to use std::vector<int> if size is not known at compile time1, and std::array<int, size> if it is2. There is no need for pointers here.
void foo(const std::vector<int>& v)
{
// do stuff with v
}
...
std::vector<int> v(size); // vector with size elements
// do something with v
// pass v to a function
foo(v);
Question 2: when I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
If you use C++ idioms you won't even encounter this problem, so I consider the question moot. However, in your case you have a problem of operator precedence: be explicit about applying de-reference * before access []:
cout<< (*parray)[k] << " ";
1 As shown in the example, you can use an std::vector as a fixed size array, where the size need not be known at runtime. Just bear in mind that it is possible to change it's size after construction.
2In your example, size is not a compile time constant so you cannot use std::array. However, if you had declared it as const int size = 100; then it would be considered a compile time constant.
Your code is a bit off in three ways. First, there is no need to use &theray. Array names already reference a memory address. You can simply assign the pointer to theray. Second, you're declaring an array of 100 pointers. Based on your description, it sounds like you just want one pointer that points to the array. Your declaration should just be int *parray instead of int *parray [100]. Finally, once you have a pointer to the array, you can access elements of the array the same way you would with the original array, only with the name of the pointer, instead of the name of the array. Try changing your last block of code (starting with the pointer declaration to this:
int *parray;
parray = theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<parray[k]<<" ";
}
Question 1
Is this the right approach?
Usually not. It depends on what you are trying to achieve.
For high level semantics you'd in most cases use std::vector<int> or, if the size is fixed and you are using C++11, std::array<int, size>. If you actually have to go down to the pointer level, you'd usually write it like this:
int *parray = theray;
cout<<"The array pointer: ";
for(int k=0; k<size; k++)
{
cout<<parray[k]<<" ";
}
This works because arrays will degrade to pointers, and the […] subscripts work on these pointers just like they work on the original arrays.
Question 2
When I run the code below, my pointer function generates values inconsistent with what the actual array's value is, what am I doing wrong?
*parray[k] gets interpreted as *(parray[k]) while you intend to use it as (*parray)[k].
Question 1: is this the right approach?
No. Use std::vector<> for arrays whose size can change dynamically (at run-time). Prefer avoiding pointers and manual memory management.
Question 2: when I run the code below, my pointer function generates values inconsistent with what the actual array's value is. What am I doing wrong?
First of all, the fact of creating pointers so you can pass the array to a function. This is not necessary. Here is how I would use classes from the C++ Standard Library to write that program (in C++11):
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
// Sample function that prints the vectors's content
void foo(std::vector<int> const& v)
{
copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " "));
}
int main()
{
// Populate the vector...
size_t sz = 10;
std::vector<int> v(sz);
generate(begin(v), end(v), [] () { return rand() % 100; });
// Pass it to a function...
foo(v);
}

stl map, set error: memory clobbered past end of allocated block

As I tried to solve this interview problem: find the sum of continuous element in an array which equals to a target number, so I come up with the following code. However, I really don't understand why it has some memory allocation problem. Here is the link to the full code. when I tried to insert the second element of currSum into the set and map, it will have some error message like "memory clobbered past end of allocated block". Isn't set, map dynamically allocated for insert? I really don't understand why it's not working as I think.
I also paste the full code here:
#include <map>
#include <set>
#include <iostream>
using namespace std;
void print_array(int arr[], int start, int end)
{
for(int i=start;i<=end;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
//given an array, find the continous sum of the array which is a target number
void findTargetSum(int arr[], int target, int sizeArr)
{
map<int, int> valIdxMap;
set<int> prevSet;
int* currSum= new int(sizeArr+1);
currSum[0]=0;
for(int i=1;i<=sizeArr;i++)
{
currSum[i]=currSum[i-1]+arr[i-1];
}
//now the problem is to find two elements i, j in array currSum,where currSum[j]-currSum[i]=target && j>i
for(int i=0; i<=sizeArr;i++)
{
int tmp=currSum[i]-target;
set<int>::iterator iter=prevSet.find(tmp);
if (iter !=prevSet.end())
{
cout<<"located one range of array elements with sum to"<<target<<endl;
int startIdx=valIdxMap[*iter];
print_array(arr,startIdx,i-1);
}
else
{
prevSet.insert(currSum[i]);
valIdxMap.insert(make_pair(currSum[i],i));
}
}
delete currSum;
}
void testfindTargetSum()
{
int tst_arr[]={2,4,5,-1,3,8};
int target=11;
findTargetSum(tst_arr,11,6);
}
int main()
{
testfindTargetSum();
return 1;
}
The error is in this line:
int* currSum= new int(sizeArr+1);
That line acquires a single int and initializes it to the value sizeArr+1. You probably meant:
int* currSum= new int[sizeArr+1];
That will acquire a block of sizeArr+1 elements of type int. Additionally you will have to change the line delete currSum; to be delete [] currSum;.
My advice, on the other hand, would be not to manage memory manually but use a standard container, for example:
std::vector<int> currSum( sizeArr+1 );
Will basically be an in-place replacement for your current implementation and it will manage memory automatically.
As of the implementation, I believe that you can actually do it without any extra memory in O(N) by accumulating the start index, end index and sum of the values in three variables while iterating. While the accumulated value is smaller than the target, increment the end index and add the value. When the accumulated value grows higher than the target, increment the start index and decrement the accumulated value by that amount.
you wrote
int* currSum= new int(sizeArr+1);
you probably meant
int* currSum= new int[sizeArr+1];

While inserting nodes in heap how to use bubble up?

Following is my code which doesnot properly bubbles up the larger value .Can any one help out .The problem is somewhat at count++ .
#include<iostream>
using namespace std;
class heap{
public:
int count;
heap(int c)
{
count=c;
}
int Arr[10];
void insert(int num);
void deletemax();
void print();
};
void heap::insert(int num){
if(count==10){
cout<<"Heap full\n";
exit(1);
}
else{
Arr[count]=num;
count++; //The real problem arises here that the compiler adds 1 to count and when the code moves ahead it sets position var to count++ value and tries to compare a value at Arr[POS] with its parent whereas there is no value at this place set uptill.
}
int POS=count;
while(Arr[POS]>Arr[(POS-1)/2]){
int temp;
temp=Arr[POS];
Arr[(POS-1)/2]=temp;
POS=(POS-1)/2;
}
}
void heap::print(){
for(int i=0; i<10; i++){
cout<<Arr[i]<<endl;
}
}
int main(){
heap h(0);
int a;
int b=0;
while(b<10){
cout<<"Insert node in heap\n";
cin>>a;
h.insert(a);
b++;
}
h.print();
return 0;
}
I would agree, that's where your problem is.
There are many issues with the code you posted, some of which include:
As to your specific issue, I would guess you need to change the line in heap::insert() to "int POS=count-1;" to properly start iterating from the back of the array.
You need to consider the case of adding an element to an empty array and what then happens in your sorting code.
Your constructor allows someone to create a heap that will overflow the fixed sized array, for example heap(1000). In addition, the Arr member is not initialized which means it has undefined data for any value but heap(0). In this case your constructor should not take any parameters and count should just be initialized to 0.
The purpose of the code is confusing. Is it a heap, a sorted array, an attempt to approximate a heap with an array, none of the above? If you are simply trying to implement a fixed sized sorted array then I believe your sorting code in insert() will not work (e.g., consider adding 100 to a heap containing [1,2,3]).
There are other, more basic things, wrong (like not using any the STL containers, public class member, non-const parameter passing, "using std", etc...) but I'm assuming you are merely experimenting/playing here.