Can't Access some values in an array using a pointer - c++

So I was asked to write a program which uses a pointer that points to the first element in an array and pass the pointer to a function. Then using only pointer variables (and looping constructs), print only the array values that are exact multiples of 7. Here's the script:
#include <iostream>
using namespace std;
void print_sevens(int *nums,int length){
for(int i = 0; i < length; i++){
nums = nums + i;
if(*nums % 7 == 0)
cout << *nums << endl;
}
}
int main() {
int a[5]={7,49,2,8,70};
int *p1 = &a[0];
print_sevens(p1,5);
}
The output from this is :
7
49
-149462114
I can't find out what is wrong. Any help is appreciated. Thanks

nums is the pointer to the start of the array. You are reassigning it at every loop iteration to be nums + i, not nums + 1. So, at the fourth iteration, for example, nums points to the initial array start + 0 + 1 + 2 + 3, which is the seventh element in your array of 5 elements. That's why you get garbage.
Use a subscript to make your life easy:
for(int i = 0; i < length; i++){
if(nums[i] % 7 == 0)
cout << nums[i] << endl;
}

Related

Where is the array getting that value from?

So here's a simple program that just search for two numbers in an array that sum up to a certain value k
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
unordered_set<int> hashtable;
int k =7;
int arr[5] = {1, 2, 3, 4, 5};
int s = sizeof(arr);
for (int i =0; i<s; i++){
if( hashtable.find(k - arr[i])!= hashtable.end() )
{
cout << arr[i] << endl;
cout<< "found one " << arr[i] << " and "<< k-arr[i]<< endl;
} else {
hashtable.insert(arr[i]);
}
}
return 0;
}
And here's the out put, I am getting
4
found one 4 and 3
5
found one 5 and 2
7
found one 7 and 0
7
found one 7 and 0
Am I missing something?
You access the array outside of its bounds. The behaviour of the program is undefined.
sizeof does not yield the number of elements in an array. It yields the size of an object in bytes. When the size of the element is more than one byte - and int is more than one byte on most systems - then the number of bytes in the array is more than the number of elements.
A correct way to get the number of elements in an array is to use std::size:
int s = std::size(arr);
Since you use only arr[i] and not i itself, you can write for (auto a : arr). This will respect the array bounds, you don't need to calculate the maximum index. Hence, it avoids the wrong calculation (which the other answers fix)
Maybe there are other ways to get the size of an array but for now this will do :
int s = sizeof(arr)/sizeof(arr[0]);

c++ array of pointers and memory address allocation

Can someone explain how an array of pointers implementation of c++ dynamically?
Is the below code correct?
If so,
int *ptr[5];
for (int i = 0; i < 5; i++)
{
int size = 2;
ptr[i] = new int [size] ;
//*(ptr + i) = new int[size]; this is the same as above line
cout << &ptr[i] << endl; ----------> line 1
cout << ptr[i] << endl; -----------> line 2
}
What is actually printing in line 1 and 2 ?
this is the addresses i get for line 1
0x7fff88f805d0
0x7fff88f805d8
0x7fff88f805e0
0x7fff88f805e8
0x7fff88f805f0
this is the addresses I get for line 2
0x55f946348ef0
0x55f946349330
0x55f946349360
0x55f946349390
0x55f9463493c0
Can somebody explain this whole mess of pointer arrays.
The picture provides a graphical explanation to the problem if anyone gets
confused with the array of pointers concept with dynamically allocating the array of pointers to new int or any other type array
int *ptr[2]; // statically declared pointer array stack
int p [2];
for (int i = 0; i < 2; i++)
{
int size = 2;
ptr[i] = new int[size];
cout << i << " array of int " << endl;
//*(ptr + i) = new int[size];
for (int j = 0; j < size; j++)
{
cout << "value : " ;
cout << *(ptr[i] + j) ; // <------- this should give 0's as value
//cout << (ptr[i])[j] ; <------ same thing
cout << " address :";
cout << ptr[i] + j << endl; //<----- these are in order as well since it's an array of type int
}
}
0 array of int
value : 0 address :0x564c9ede32c0
value : 0 address :0x564c9ede32c4
value : 0 address :0x564c9ede32c8
1 array of int
value : 0 address :0x564c9ede32e0
value : 0 address :0x564c9ede32e4
value : 0 address :0x564c9ede32e8
I am assuming you want to perform operation on dynamic array like adding element and printing;
Remember:In int *ptr=new int[5]; sizeof(ptr) is 8 bytes on stack memory and array will be stored in heap memory.
We will fetch the element via pointer ptr and every element will be fetched as per type of array (say int ) then ptr will go to 0th index element and read the data of it as int type (only 4 bytes as int is of 4 byte generally) and move to next index till end.
Look into code below:
#include <iostream>
using namespace std;
int main() {
int *ptr=new int[5]; //let size = 5
for(int i=0; i<5;i++){
cin>>ptr[i];
}
for(int i=0; i<5;i++){
cout<<&ptr[i]<<":"; //this will print every element's address per iteration
cout<<ptr[i]<<endl; //this will print every element as per input you gave
}
delete []ptr; //remember it's not delete ptr ask if required
return 0;
}
Now See the the output and dry run yourself you can understand
Output
0x556999c63e70:1
0x556999c63e74:2
0x556999c63e78:3
0x556999c63e7c:4
0x556999c63e80:5
Benefit of dynamic array is you can create dynamic sized array by taking size input as per user choice pass that variable is size of dynamic array
i.e you can change above size=5 to 'N' a variable one .
I think this might help you else you can ask for any further clarification.

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.

Swap elements in array to reverse an array

I got an assignment to reverse an dynamic array in C++. So far, from my logic, I thinking of loop thru the array to reverse it. And here comes my code :
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< sizeof(num_array)/sizeof(num_array[0]) ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array[size],size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], int size)
{
for (int count =0; count< sizeof(num_array)/sizeof(num_array[0]); count++){
cout << num_array[sizeof(num_array)/sizeof(num_array[0])-1-count] << " " ;
}
return;
}
Somehow I think my logic was there but this code doesn't works, there's some error. However, my teacher told me that this isn't the way what the question wants. And here is the question :
Write a function reverse that reverses the sequence of elements in an array. For example, if reverse is called with an array containing 1 4 9 16 9 7 4 9 11,
then the array is changed to 11 9 4 7 9 16 9 4 1.
So far, she told us in the reverse method, you need to swap for the array element. So here's my question how to swap array element so that the array entered would be reversed?
Thanks in advance.
Updated portion
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< size ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array,size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], const int& size)
{
for (int count =0; count< size/2; count++){
int first = num_array[0];
int last = num_array[count-1];
int temp = first;
first = last;
last = temp;
}
}
You reverse function should look like this:
void reverse(int* array, const size_t size)
{
for (size_t i = 0; i < size / 2; i++)
{
// Do stuff...
}
}
And call it like:
reverse(num_array, size);
I am no C++ programmer, however I do see an easy solution to this problem. By simply using a for loop and an extra array (of the same size) you should be able to reverse the array with ease.
By using a for loop, starting at the last element of the array, and adding them in sequence to the new array, it should be fairly simple to end up with a reversed array. It would be something like this:
Declare two arrays of the same size (10 it seems)
Array1 contains your random numbers
Array2 is empty, but can consist of 10 elements
Also declare an integer, which will keep track of the progression of the for loop, but in the opposite direction. i.e not from the end but from the start.
Counter = 0
Next you will need to create a for loop to start from the end of the first array, and add the values to the start of the second array. Thus we will create a for loop to do so. The for loop will be something like this:
for(int i = lengthOfArray1; i > 0; i--){
Array2[Counter] = Array1[i]
Counter++
}
If you only wish to print it out, you would not need the counter, or the second array, you will simply use the Array1 elements and print them out with that style of for loop.
That's it. You could set Array1 = Array2 afterward if you wished to keep Array1 the original for some reason. Hope this helps a bit, changing it to C++ is your job on this one unfortunately.
You're not actually swapping the elements in the array, you're just printing them out. I assume she wants you to actually change what is stored in the array.
As a hint, go through the array swapping the first and last element, then the 2nd and 2nd last element, etc. You only need to loop for size/2 too. As you have the size variable, just use that instead of all the sizeof stuff you're doing.
I would implement the function like following
void reverse(int A[], int N)
{
for (int i=0, j=N-1; i<j; i++, j--){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
}

Convert one dimensional array to two dimensional array

For my homework it is given one dimensional array and i have to convert it in a two dimensional array. The two dimensional array has 2 for the number of columns, because i have to represent the one dimensional array as pairs(the value of the number, the number of appearences in the array).
This is what have tried. The error appears on the last 2 lines of code: access violation writing location 0xfdfdfdfd.
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
const int NR=17;
int arr[NR]={6,7,3,1,3,2,4,4,7,5,1,1,5,6,6,4,5};
int **newArr;
int count=0;
int countLines=0;
int searched;
for(int i=0;i<NR;i++)
{
newArr=new int*[countLines];
for(int i=0;i<countLines;i++)
{
newArr[i]=new int[2];
}
searched=arr[i];
if(i>0)
{
for(int k=0;k<countLines;k++)
{
if(newArr[countLines][0] == searched)
{
searched=arr[i]++;
}
for(int j=0;j<NR;j++)
{
if(searched==arr[j])
{
count++;
}
}
countLines++;
}
}
else
{
for(int j=0;j<NR;j++)
{
if(searched==arr[j])
{
count++;
}
}
countLines++;
}
newArr[countLines][0]=searched;
newArr[countLines][1]=count;
}
}
First you are using newArr in the first loop before allocating it any memory. You cannot dereference a pointer which owns no legal memory. It results in undefined behavior.
Secondly in the last part, you are allocating newArr a memory equal to countLines thus.
newArr = new int*[countLines] ;
It means that the indices in the first dimension of newArr are 0------>countLines-1. Doing newArr[countLines][0] = searched ; is again undefined. Make it newArr[countLines - 1].
I'm not going to bother with a line-by-line code analysis since (a) you're changing it while people are answering your question and (b) it would literally take too long. But here's a summary (non-exhaustive) of klunkers:
You are leaking memory (newArr) on each loop iteration starting with the second.
You're out-of-bounds on your array access multiple times.
You should not need to use a pointer array at all to solve this. A single array of dimension [N][2] where N is the number of unique values.
One (of countless many) way you can solve this problem is presented below:
#include <iostream>
#include <algorithm>
int main()
{
// 0. Declare array and length
int arr[]={6,7,3,1,3,2,4,4,7,5,1,1,5,6,6,4,5};
const size_t NR = sizeof(arr)/sizeof(arr[0]);
// 1. sort the input array
std::sort(arr, arr+NR);
/* alternaive sort. for this input size bubble-sort is
more than adequate, in case your limited to not being
allowed to use the standard library sort */
/*
for (size_t i=0;i<NR;++i)
for (size_t j=i+1;j<NR;++j)
if (arr[i] > arr[j])
{
arr[i] ^= arr[j];
arr[j] ^= arr[i];
arr[i] ^= arr[j];
}
*/
// 2. single scan to determine distinct values
size_t unique = 1;
for (size_t i=1;i<NR;++i)
if (arr[i] != arr[i-1])
unique++;
// 3. Allocate a [unique][2] array
int (*newArr)[2] = new int[unique][2];
// 4. Walk array once more, accumulating counts
size_t j=0;
newArr[j][0] = arr[0];
newArr[j][1] = 1;
for (size_t i=1;i<NR;++i)
{
if (arr[i] != arr[i-1])
{
newArr[++j][0] = arr[i];
newArr[j][1] = 0;
}
++newArr[j][1];
}
// 5. Dump output
for (size_t i=0;i<unique;++i)
cout << newArr[i][0] << " : " << newArr[i][1] << endl;
delete [] newArr;
return EXIT_SUCCESS;
}
Output
1 : 3
2 : 1
3 : 2
4 : 3
5 : 3
6 : 3
7 : 2