i have been trying to insert a new element into a given array at a given index. though i am able to insert new element but i have few doubts..
why it got inserted at 7th index instead at 3?
how value of variable k become 7?
why size of old and new array is same though new array has 1 more element?
thanks in advance. any help would be appreciated.
int main()
{
int arr[] = {1,2,3,4,5,6,7};
int n = sizeof(arr)/sizeof(arr[0]);
int k = 3;
cout << "elements of old array" << endl;
for (int i=0; i<n; i++){
cout << arr[i] << endl;
}
cout << "size of old array " << sizeof(arr) << endl << endl << endl;
// inserting new element
for (int j=n; j>k; j--){
arr[j] = arr[j-1];
}
arr[k] = 10;
cout << "elements of new array " << endl;
for (int i=0; i<=n; i++){
cout << arr[i] << endl;
}
cout << "size of new array " << sizeof(arr)<< endl ;
}
Classic C Memory Question!
When you declare arr as an array it has a fixed length ... thus a fixed amount of space in memory. By shifting all the elements of arr to the right, you are not actually increasing the size of arr, you are just writing over whatever memory is directly adjacent to arr.
This explains why k is being set to 7. k must be stored adjacent to the end of arr in memory. Thus, when you shift arr[n-1] to arr[n], k is being set to 7.
If you want to fix this, I would suggest making a new array of size n + 1, then copying all the elements over with their new indices.
An array has a fixed size once it's created; your array has length 7, and that's it - it's not going to change.
Your code shifts the array along by one element, which involves writing to arr[7], which means 'store this value in the eighth element of array arr', and the compiler happily does that - there's no bounds checking for arrays in C++. However, it does not extend the length of the array, it just writes to the memory where the eighth element would be if the array was eight elements long.
In your code, it so happens that the memory where the eighth element would be is actually where the variable k is stored, which is why the value of k changes to 7 (I suspect that the variable n has been optimised away, otherwise it would have been n that got changed).
To make a long story short, handling arrays in C++ (and C) is fraught with danger and you have to be very careful. In any current and/or production code, you should use a std::vector instead.
Related
I have the following main program that creates a Stack object, fills it with integers and then pops them. The code files fine, but the pop_back() part does not seem to work, even after pop_back() it prints all values. How is this possible?
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> myVector; //initalization
int value;
//input in a vector using push_back
for (int i = 0; i < 6;i++){
cin >> value;
myVector.push_back(value);
}
cout<<"Initial vector size:" << myVector.size() <<endl;
for (int i = 0; i < 6;i++){
cout << myVector[i];
}
cout << endl;
myVector.pop_back();
cout<<"Vector size after pop back: " << myVector.size() << endl;
cout << endl;
cout << "First element is: " << myVector.front() << endl;
cout << "Last element is : " << myVector.back() << endl;
for (int i = 0; i < 6;i++){
cout << myVector[i];
}
return 0;
}
Everyone has focused on saying this is undefined behavior fix code, but question was why it works.
To understand why it works you must understand how vector works more or less.
Vector allocates some block of memory to store items.
size of this block is defined by capacity, which says how many items can be stored in vector, without allocating new block of memory
capacity is usually bigger then size of the vector
now when you remove items form vector, capacity and allocated block of memory doesn't change. This is an optimization.
when you remove item from back just destructor is called (for int it does nothing) and size of vector is reduced.
your value is not cleared just marked as out of vector size
so when you use operator[] it doesn't check if you exceed its size. It just returns value at specific adders
since pop_back just reduced size you value is still there
Note if you call shrink_to_fit after pop_back there is a great chance it will and with crash or you will not receive same value. Still this is undefined behavior and anything can happen.
Another way to see your code is bad is to use at which checks if index is in valid range.
std::vector::pop_back function works just fine. After you perform a call to it, you try to print all 6 values instead of 5. Therefore, you are accessing invalid memory. In your case, program prints out the value that was removed but in some other case it could print some garbage value. That's why this is UB - Undefined Behavior.
Try the following and you will see that last element is not in the std::vector:
for (int i = 0; i < myVector.size(); i++) {
std::cout << myVector[i];
}
or, even better, use range-based for loop:
for (auto const i : myVector) {
std::cout << i;
}
The problem is in the way you loop through the vector - you are expecting it to have 6 elements even after you have removed the last element. This is undefined behavior.
Using a range based for would be preferred in both cases where you want to output the contents of the vector:
for (auto i:myVector) {
cout << i;
}
As I describe above, always there is 12 Byte gap by each row when I allocate 2 dimension array dynamically.
In that code, I expected ppa[1] to be 0x1005626e4. But result is 0x1005626f0. I know dynamic allocation may not allocated in contiguous space. But there is always at least 12 Byte gap.(Actually some times each row allocated in different space)
I know when allocate in heap, need some space for store information. Eg size, type..
Is that reason of 12 Byte? If someone know real reason of 12 Byte tell me about that.
Code
int** ppa;
ppa = new int*[3];
for (int i = 0; i < 3; ++i) {
ppa[i] = new int[5];
cout << "ppa[" << i << "]: " << ppa[i] << endl;
for (int j = 0; j < 5; ++j) {
cout << "&ppa[" << i << "][" << j << "]: " << &ppa[i][j] << endl;
}
cout << endl;
}
output
ppa[0]: 0x1005626d0
&ppa[0][0]: 0x1005626d0
&ppa[0][1]: 0x1005626d4
&ppa[0][2]: 0x1005626d8
&ppa[0][3]: 0x1005626dc
&ppa[0][4]: 0x1005626e0
ppa[1]: 0x1005626f0
&ppa[1][0]: 0x1005626f0
&ppa[1][1]: 0x1005626f4
&ppa[1][2]: 0x1005626f8
&ppa[1][3]: 0x1005626fc
&ppa[1][4]: 0x100562700
ppa[2]: 0x100562710
&ppa[2][0]: 0x100562710
&ppa[2][1]: 0x100562714
&ppa[2][2]: 0x100562718
&ppa[2][3]: 0x10056271c
&ppa[2][4]: 0x100562720
My Test Environment
OS: OSX 64bit system
IDE: Xcode
What you do is creating a jagged array where there's no requirement that sub-arrays have to be allocated contiguously.
You simply get what the memory allocator gives you.
As pointed out above, you are allocating references of 3 different 1-D arrays (to ppa[i]) afterwards. However, these 1-D arrays may be assigned any memory address in the memory(no specific pattern of 12byte gap). The only ensured thing is that the elements inside 3 of these 1-D arrays will be contiguous.
Note:- If you create array such as "int ppa[3][5]", then all the elements will be contiguous.
Probably some internal information about allocated block is stored there.
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
Here it is:
#include <iostream>
#include <cstdlib> // for rand() and srand()
#include <ctime>
using namespace
int main()
{
//cout << "How many players?" << endl;
int numplayers=1;
//cin >> numplayers;
int players[numplayers];
int x=0,y=0;
srand(time(0));
x=(rand() % 6 + 1);
y=(rand() % 6 + 1);
players[1]=players[1]+x+y;
cout << ("Your score is" + players[1]) << endl;
cin >> numplayers;
}
Ok My original problem was that this always crashed, now it prints "#"???
C++ arrays are 0 based.
players[1] is accessing a location outside the range of the array.
You will want: players[0].
cout << ("Your score is" + players[1]) << endl;
Here you're trying to use direct string concatenation, but you can't concatenate a string literal with an integer like that. You end up doing pointer arithmetic, which is definitely not what you intended.
You should instead use cout's built-in formatting:
cout << "Your score is" << players[1] << endl;
Your next problem is that players is not declared correctly; an array cannot have runtime bounds, and numplayers (despite having only the one initial value) is ultimately a "runtime" variable. You would be better off with a std::vector if the size of the array is going to change later; otherwise make numplayers a constexpr.
Your last problem is that, if the array declaration were valid, you'd be trying to access the second element of a one-element array! The first element is players[0], not players[1].
There are many things you're doing not good.
I believe you're using C++, there is no known way to me about creating arrays of dynamic size i.e. int players[numplayers]. In C++ either we can create array of fixed size i.e. int players[10] or use pointer to an array for dynamically allocated memory e.g. int* players = new int[numplayers]. This allocates an array of size numplayers and an int pointer named players is pointing to it. We can use this pointer as normal array e.g. printing 1st index of array is written as player[0] or another syntax is *(player + 0). Remember to delete this dynamically allocated memory at the end of program i.e. delete[] player.
Second thing is when you have allocated an array and are using its value for computation, always initialize it to 0 as newly allocated array contains garbage value and it will affect your computations. code for initializing it to zero may be like this:
Here is the loop:
for(int i = 0 ; i < numplayers ; i++){
player[i]=0;
//another syntax is : *(player + i) = 0;
}
C++ does not concat as you did in your std::cout statement. Make it like this:
cout << "Your score is" << players[0] << endl;
In C++, arrays always start with index zero, so 1st index will be 0 in this case. So your program will work well if it is like this:
int numplayers = 1;
int* players = new int[numplayers];
int x = 0, y = 0;
srand(time(0));
x = (rand() % 6 + 1);
y = (rand() % 6 + 1);
players[0] = 0;
players[0] = players[0] + x + y;
cout << "Your score is" << players[0] << endl;
delete[] players;
return 0;
Definitely it crashes for the below line:
players[1]=players[1]+x+y;
Because size of players array is 1, so it has only index 0. And in above line, it tries to access index 1. Take a look at Buffer Overflow and array index out of bounds.
Try to define an array with constant size.
If you need a dynamic array, use linked list or vector.
Trying to insert values into a 2D array, but the output isnt giving my values, instead random letters
int myArr[8][2] = {700,730,760,790,810,840,910,1000}{0.011,0.035,0.105,0.343,0.789,2.17,20,145};
cout << myArr << endl;
system("Pause");
How should I adjust the code, or is it easier to use a text file and insert?
Numerous problems:
the array dimensions are wrong
you don't have outer braces or a comma for the nested arrays
you're trying to store double precision floating point values in an int array
you can't use cout with an entire array.
The array declaration should probably be something like this:
double myArr[2][8] = { {700,730,760,790,810,840,910,1000},
{0.011,0.035,0.105,0.343,0.789,2.17,20,145} };
and to output the contents you could do something like this:
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 8; ++j)
{
cout << " " << myArr[i][j];
}
cout << endl;
}
Live Demo
First - you can't print the whole array just by using cout << myArr, you need to iterate over the elements of the array using a for loop.
Second - you are trying to put decimal values into an integer array which will truncate all of the decimals.
Third - Your array should be sized myArr[8][2] not myArr[2][8]. I'm surprised your compiler lets you get away with this. You should probably look into using a different compiler.
You need to iterate through each row and column, otherwise you're just printing out the pointer value of the array handle.
for (int i=0;i<8;i++){
for (int j=0;j<2;j++){
cout << myArr[i][j] << " ";
}
cout << endl;
}
system("Pause");
I am trying to output the values present in the array, that are accepted during runtime, onto the console. But when I run this program I get the 5 values in the array as the last value only.
For example: if i give 0 1 2 3 4 as the five values for this program then the output is shown as 4 4 4 4 4.
#include "stdafx.h"
#include<iostream>
using namespace std;
int main()
{
int arrsize = 5;
int *ptr = new int[arrsize];
*ptr = 7;
cout << *ptr << endl;
cout << "enter 5 values:";
for (int i = 0; i < arrsize; i++)
{
cin >> *ptr;
cin.get();
}
cout << "the values in the array are:\n ";
for (int i = 0; i < arrsize; i++)
{
cout << *ptr << " ";
}
delete[] ptr;
cin.get();
return 0;
}
Both of your loops:
for (int i = 0; i < arrsize; i++)
...
loop over a variable i that is never used inside the loop. You are always using *ptr which refers always to the first element of the dynamically allocated array. You should use ptr[i] instead.
A part from that, dynamic allocation is an advanced topic. I'd recommend sticking with simpler and more commonly used things first:
std::cout << "Enter values:";
std::vector<int> array(std::istream_iterator<int>(std::cin), {});
std::cout << "\nThe values in the array are:\n";
std::copy(begin(array), end(array), std::ostream_iterator<int>(std::cout, " "));
Live demo
Following issues I think you could tackle:
The first include can be omitted I think. Your code works without that.
You use cin.get(), not sure why you need that. I think you can remove that. Even the one at the very end. You could put a cout << endl for the last newline. I am using Linux.
And use ptr like an array with index: ptr[i] in the loops as mentioned in the other answer. ptr[i] is equivalent to *(ptr+i). You have to offset it, otherwise you're overwriting the same value (that is why you get that result), because ptr points to the first element of the array.
P.S.: It seems that if you're using Windows (or other systems) you need the cin.get() to avoid the console to close down or so. So maybe you'd need to check it. See comments below.