I would like to understand how does it works to scan a dynamically allocated two-dimensional array using pointers arithmetics?
I can't figurate why in my example pointer arithmetic isn't returning the same results as using array indexing.
Here is my implementation:
#include <iostream>
using namespace std;
void init_matrix(int ** m, int size);
void print_matrix(int ** m, int size);
void print_matrix_pointers(int ** m, int size);
int main (){
srand (time(NULL));
int size = 3;
int ** dynamic_matrix = new int * [size];
for (int i = 0; i < 10; i++) {
dynamic_matrix[i] = new int [size];
}
init_matrix(dynamic_matrix, size);
cout << "Dynamic matrix accessed using square brackets ([i][j]): " << endl;
print_matrix(dynamic_matrix, size);
cout << "Dynamic matrix accessed using pointers arithmetics: " << endl;
print_matrix_pointers(dynamic_matrix, size);
return 0;
}
void init_matrix(int ** m, int size) {
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
m[i][j] = rand()%10;
}
}
}
void print_matrix(int ** m, int size){
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
cout << m[i][j] << " ";
}
cout << endl;
}
}
void print_matrix_pointers(int ** m, int size){
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
cout << *(*m + (i * size) + j) << " "; //
}
cout << endl;
}
cout << endl;
}
For instance if size was 3 I would get this output.
Dynamic matrix accessed using array indexing ([i][j]):
3 3 4
9 5 9
4 9 4
Dynamic matrix accessed using pointers arithmetics:
3 3 4
32735 9 5
9 32735 4
With *(*m + (i * size) + j) you treat m as a contiguous array of values, which it isn't. It's more like a jagged array. You need to treat it like the array of pointers it really is, like *(*(m + i) + j).
Two typos in your code:
int size = 3;
int ** dynamic_matrix = new int * [size];
for (int i = 0; i < 10; i++) {
dynamic_matrix[i] = new int [size];
}
size is 3 but you write 10 elements. That is undefined behavior.
Then you are advancing the pointer wrongly.
void print_matrix_pointers(int ** m, int size){
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
cout << *( *(m + i) + j) << " "; //
}
cout << endl;
}
cout << endl;
}
m points to an array of pointers to int. You have to increment m by i to get to the i-th row. Then you want to access the jth element of the array pointed to by m[i], hence you have to first dereference m+i then add j to get the address of jth element.
Related
The question I am trying to solve is the following:
Write a function that traverses (and prints) the element of an array with stride =7. To do this the update part in the loop will be i= (i+7) % n, where n is the array size.
Would this function visit all elements of the array? Try different array sizes to check when it is impossible to traverse all elements.
The code that I wrote below doesn't print the correct values in the arry even if the value of i is correct.
Can anyone help, I would really appreciate it.
#include <fstream>
#include <stdlib.h>
using namespace std;
int* CreateArray(int n);
void StrideArray(int arr[], int n);
int main()
{
int* arr = new int[3];
arr = CreateArray(3);
cout << "The Elements In The Array Are: " << endl;
for (int i = 0; i < 3; i++)
{
cout << arr[i] << " ";
}
cout << endl;
StrideArray(arr, 3);
cout << "The Elements In The Array Stride 7 Are: " << endl;
for (int i = 0; i < 3; i++)
{
cout << arr[i] << " ";
}
delete[] arr;
return 0;
}
int* CreateArray(int n)
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = (rand() % 100);
}
return arr;
}
void StrideArray(int arr[], int n)
{
int i = 0;
for (int j = 0; j < n; j++)
{
i = (i + 7) % n;
arr[j] = arr[i];
}
}
The problem is in StrideArray you read back the modified values of arr.
void StrideArray(int arr[], int n)
{
int i = 0;
int puffer=new int[n];
for (int j = 0; j < n; j++)
{
i = (i + 7) % n;
puffer[j] = arr[i];
}
for (int j = 0; j < n; j++){
puffer[j] = arr[j];
}
debete[] puffer;
}
Is a good way to write the function.
Also it visits all element only if n isn't dividable by 7. So if n is not 7,14,21,...
Also to use cout you have to #include <iostream>
Your StrideArray function needs fixing; you are iterating over j but using i to index, which remains constant; and you are reassigning value at one index to another where as you are supposed to print it:
void StrideArray(int arr[], int n)
{
int i = 0;
for (int j = 0; j < n; j=j+7)
{
cout << arr[j] << endl;
}
}
I modified the rest of your code for demo:
#include <iostream>
#include <stdlib.h>
using namespace std;
int* CreateArray(int n);
void StrideArray(int arr[], int n);
int main()
{
int* arr = new int[3];
arr = CreateArray(21);
cout << "The Elements In The Array Are: " << endl;
for (int i = 0; i < 21; i++)
{
cout << arr[i] << " ";
}
cout << endl;
StrideArray(arr, 21);
delete[] arr;
return 0;
}
int* CreateArray(int n)
{
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = (rand() % 100);
}
return arr;
}
I have a program, where I have to generate all R-digit numbers among N digits in C++, for example for N=3 (all digits from 1 to N inclusive) and R=2 the program should generate 12 13 21 23 31 32. I tried to do this with arrays as follows, but it does not seem to work correctly.
#define nmax 20
#include <iostream>
using namespace std;
int n, r;
void print(int[]);
int main()
{
cin >> n;
cin >> r;
int a[nmax];
int b[nmax];
int used[nmax];
for (int p = 1; p <= n; p++) {
//Filling the a[] array with numbers from 1 to n
a[p] = n;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < r; j++) {
b[j] = a[i];
used[j] = 1;
if (used[j]) {
b[j] = a[i + 1];
}
used[j] = 0;
}
print(b);
}
return 0;
}
void print(int k[]) {
for (int i = 0; i < r; i++) {
cout << k[i];
}
}
If I understand your question correctly, you can explore this website where it explains the problem and suggests the solution thoroughly.
Here is a slightly altered code:
Pay attention that time is an issue for bigger N values.
#define N 5 // number of elements to permute. Let N > 2
#include <iostream>
using namespace std;
// NOTICE: Original Copyright 1991-2010, Phillip Paul Fuchs
void PrintPerm(unsigned int *a, unsigned int j, unsigned int i){
for(unsigned int x = 0; x < N; x++)
cout << " " << a[x];
cout << " swapped( " << j << " , " << i << " )\n";
}
void QuickPerm(void){
unsigned int a[N], p[N+1];
register unsigned int i, j, PermCounter = 1; // Upper Index i; Lower Index j
for(i = 0; i < N; i++){ // initialize arrays; a[N] can be any type
a[i] = i + 1; // a[i] value is not revealed and can be arbitrary
p[i] = i;
}
p[N] = N; // p[N] > 0 controls iteration and the index boundary for i
PrintPerm(a, 0, 0); // remove comment to PrintPerm array a[]
i = 1; // setup first swap points to be 1 and 0 respectively (i & j)
while(i < N){
p[i]--; // decrease index "weight" for i by one
j = i % 2 * p[i]; // IF i is odd then j = p[i] otherwise j = 0
swap(a[i], a[j]); // swap(a[j], a[i])
PrintPerm(a, j, i); // remove comment to PrintPerm target array a[]
PermCounter++;
i = 1; // reset index i to 1 (assumed)
while (!p[i]) { // while (p[i] == 0)
p[i] = i; // reset p[i] zero value
i++; // set new index value for i (increase by one)
} // while(!p[i])
} // while(i < N)
cout << "\n\n ---> " << PermCounter << " permutations. \n\n\n";
} // QuickPerm()
int main(){
QuickPerm();
} //main
Here is a list of the modified items from the original code.
N defined to be 5 instead of 12.
A Counter has been added for more informative result.
The original swap instructions reduced by using c++ standard libraries' swap() function.
The getch() has been removed.
The 'Display()' function has been renamed to be 'PrintPerm()'.
The printf() function has been replaced by cout.
Printing number of permutation has been added.
I'm having problems figuring out where my bubble sort code went wrong. I'm almost positive it's in the sorting algorithm. Here is what I need my code to accomplish:
-Initialize an array a fill it with random numbers (I use getNumbers() to accomplish this)
-Compare the first element with all later elements. If the first element is larger, swap them.
-Compare the second element with all later elements one by one. If the second element is larger, swap them.
-Continue comparing and swap operations until the second to last element.
-Print out the sorted array
And here's my code:
#include <iostream>
#include <cstdlib>
using namespace std;
void swap(int *, int *);
int *getNumbers(int);
int main()
{
//Get the size of the array from keyboard
int arraySize;
cout << "How many integers would you like to declare: ";
cin >> arraySize;
//Initialize array
int *array;
array = getNumbers(arraySize); //getNumbers should return a pointer
//Print out original array
cout << "Original array" << endl;
for(int count = 0; count < arraySize; count++)
{
cout << *(array + count) << " ";
}
//Sort array using the swap function
//Have a for loop to swap numbers one by one from min to max
//Compare values using a second for loop
//Swap values if former value is larger
//swap(&array[i],&array[j]);
for(int i = 0; i < arraySize; i++)
{
for(int j = 0; j < (arraySize - 1); j++)
{
if(array[j] > array[j + 1])
{
swap(&array[i], &array[j]);
}
}
}
//Print out sorted array
cout << "\nSorted Array" << endl;
for(int count = 0; count < arraySize; count++)
{
cout << *(array + count) << " ";
}
return 0;
}
void swap(int *num1, int *num2)
{
//Keep record of original value of num1
int tempNum;
tempNum = *num1;
*num1 = *num2; //num1 value has been changed
*num2 = tempNum; //Fetch the original value of num1 and assign it to num2
}
int *getNumbers(int size)
{
int *array;
array = new int[size];
srand(time(0));
for(int i = 0; i < size; i++)
{
array[i] = rand() % 100;
}
return array;
}
Here is the correct code.
#include <iostream>
#include <cstdlib>
using namespace std;
void swap(int *, int *);
int *getNumbers(int);
int main() {
//Get the size of the array from keyboard
int arraySize;
cout << "How many integers would you like to declare: ";
cin >> arraySize;
//Initialize array
int *array;
array = getNumbers(arraySize); //getNumbers should return a pointer
//Print out original array
cout << "Original array" << endl;
for (int count = 0; count < arraySize; count++) {
cout << *(array + count) << " ";
}
//Sort array using the swap function
//Have a for loop to swap numbers one by one from min to max
//Compare values using a second for loop
//Swap values if former value is larger
//swap(&array[i],&array[j]);
for (int i = 0; i < arraySize; i++) {
for (int j = 0; j < (arraySize - 1); j++) {
if (array[j] > array[j + 1]) {
/*********** This line was changed ***********/
swap(&array[j+1], &array[j]); // You were earlier swapping ith and jth entries.
/*********************************************/
}
}
}
//Print out sorted array
cout << "\nSorted Array" << endl;
for (int count = 0; count < arraySize; count++) {
cout << *(array + count) << " ";
}
return 0;
}
void swap(int *num1, int *num2) {
//Keep record of original value of num1
int tempNum;
tempNum = *num1;
*num1 = *num2; //num1 value has been changed
*num2 = tempNum; //Fetch the original value of num1 and assign it to num2
}
int *getNumbers(int size) {
int *array;
array = new int[size];
srand(time(0));
for (int i = 0; i < size; i++) {
array[i] = rand() % 100;
}
return array;
}
You were swapping array[i] with array[j] in line 32. array[j] and array[j+1] should be swapped. Also, as pointed out by dd2, your loop bounds are not strict. The code would work correctly nonetheless but would take more steps. You can change the bound to j < (arraySize - i - 1)
Your loop bounds are not correct and swapping was wrong as well.
for(int i = 0; i < arraySize; i++)
{
for(int j = 0; j < (arraySize - i - 1); j++)
{
if(array[j] > array[j + 1])
{
swap(&array[j], &array[j+1]);
}
}
}
I have some code that is producing unexpected results. Here is the code:
#include <iostream>
using namespace std;
int **nums;
int size;
void A(int** arr)
{
int **resize;
resize = new int*[size*2];
for(int i = 0; i < size; i++)
resize[i] = new int(*arr[i]);
cout << endl;
arr = resize;
size *= 2;
delete[] resize;
}
int main()
{
size = 10;
nums = new int*[size];
for(int i = 0; i < size; i++)
nums[i] = new int(i);
for(int i = 0; i < size; i++)
cout << *nums[i] << endl;
A(nums);
cout << endl;
for(int i = (size / 2); i < size; i++)
nums[i] = new int(i);
for(int i = 0; i < size; i++)
cout << *nums[i] << endl;
}
The function A(int** arr) works fine as far as I can tell and actually resizes the array. However, in the last for loop in main(), when the array is printing, the first two elements of the array are not 0 and 1 like it is supposed to be. Here is the result I am getting:
0
1
2
3
4
5
6
7
8
9
16331248
16331712
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Those first two ints after the space are different each time the program is executed. After some debugging I found out that the first two elements print correctly until the iterator i=13 in the second to last for loop in main(). Then the first two elements in the array take on some large numbers. I am not sure why this is happening and I have been working on this for a couple of hours now :( Any help is appreciated.
A() is not modifying nums to point at the new array. Even if it were, it is deleting the new array, so nums would end up pointing at invalid memory. You need to declare the arr parameter as a reference, and delete the old array instead of the new array:
void A(int** &arr)
{
int **resize;
resize = new int*[size*2];
for(int i = 0; i < size; i++)
resize[i] = new int(*arr[i]);
cout << endl;
delete[] arr;
arr = resize;
size *= 2;
}
For what you are attempting, I think you have too much indirection. Try removing a level:
#include <iostream>
using namespace std;
int *nums;
int size;
void A(int* &arr)
{
int *resize;
resize = new int[size*2];
for(int i = 0; i < size; i++)
resize[i] = arr[i];
cout << endl;
delete[] arr;
arr = resize;
size *= 2;
}
int main()
{
size = 10;
nums = new int[size];
for(int i = 0; i < size; i++)
nums[i] = i;
for(int i = 0; i < size; i++)
cout << nums[i] << endl;
A(nums);
cout << endl;
for(int i = (size / 2); i < size; i++)
nums[i] = i;
for(int i = 0; i < size; i++)
cout << nums[i] << endl;
delete[] nums;
}
Since you are using C++, you should be using a std::vector instead of a raw array, then you can eliminate A() altogether:
#include <iostream>
#include <vector>
using namespace std;
vector<int> nums;
int main()
{
nums.resize(10);
for(int i = 0; i < nums.size(); i++)
nums[i] = i;
for(int i = 0; i < nums.size(); i++)
cout << nums[i] << endl;
nums.resize(nums.size()*2);
cout << endl << endl;
for(int i = (nums.size() / 2); i < nums.size(); i++)
nums[i] = i;
for(int i = 0; i < nums.size(); i++)
cout << nums[i] << endl;
}
First of all, your function, A, does not resize anything. It prints a newline character to standard output, it multiplies the global size variable by 2, and then it leaks some memory. That's it.
Now, because it multiplies size by 2 (going from 10, to 20), you run into a problem, here:
for(int i = (size / 2); i < size; i++)
nums[i] = new int(i);
Here, you are trying to access elements 10 through 19 of the array which nums points to. But the array which nums points to only has 10 elements (numbered 0 through 9), so your code has undefined behavior.
I'm facing some difficulties with pointers for 3D arrays in C++. I've a array of Q[3][N][N] which I want to pass to a function to print the values at [0][i][j] location (and also for [1][i][j] and [2][i][j]). How can I achieve this? Will it be more convenient to use Q[i][j][0] etc?
for 2D, the following piece of code works just fine when I give &Q[0][0] to the *var:
template <typename T>
void print2d(T *var, int I, int J){
cout << endl;
for (int j = 0; j < J; j++){
for (int i = 0; i < I; i++){
cout << setprecision(3) << setw(12) << *(var + (N*i + j));
}
cout << endl;
}
cout << endl;
}
I'm using the same approach to write a similar function for 3D which does not write out the correct values:
Can anybody let me know the correct way to point to the correct address of Q[i][j][1]. In input argument, I'm giving the address of Q[0][0][0]. Should I use different addresses (such as Q[i][j][1]) if I want to write out for that particular value of k?
template <typename T>
void print3d(T *var, int I, int J, int K){
cout << endl;
for (int j = 0; j < J; j++){
for (int i = 0; i < I; i++){
cout << setprecision(3) << setw(12) << *(var + I*J*i + I*j + K);
}
cout << endl;
}
cout << endl;
}
Sample example, N must be const.
But consider using vector.
#include <stdio.h>
#include <iostream>
using namespace std;
const int N = 5;
void func2(int* tab, int A, int B, int C)
{
printf("%d\n", tab[N*N*A + N*B + C] );
}
void func(int tab[3][N][N])
{
for (int i = 0; i < 3; ++i)
for (int j = 0; j < N; ++j, printf("\n"))
for (int k = 0; k < N; ++k)
{
printf("%d ", tab[i][j][k]);
}
}
int main()
{
int tab[3][N][N];
int p = 0;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < N; ++j)
for (int k = 0; k < N; ++k)
{
tab[i][j][k] = p++;
}
func(tab);
printf("\n");
func2((int*)tab, 1, 1, 3);
}
I agree with Adam's answer but cant comment, need more points there.
1) Arrays are not pointers. Multidimensional arrays cannot be passed via a pointer, needs to have all but one dimension constant. Here is an answer to help understand.
Cannot cast array to pointer
How do I pass a reference to a two-dimensional array to a function?
http://www.cplusplus.com/forum/articles/17108/
You might want to try vectors from STL instead.
2) Templates are compiled only when there is an instance of it used, that is why its declaration and usage is generally put in one file.
Template Compilation