Problem with copying a region from two dimensional array to another two dimensional array

I have a problem with my program. I want to copy a certain region of size SS around a pixel of index i,j from a source 2-D array named as (padded) of a bigger size to another 2-D array named as (R) of size S*S . I get the location of the index i,j in the bigger array as K,l and copy the region of size S * S around this pixel to the smaller array . If S = 3 the code works fine, otherwise bigger than 3, it through access violation exception in the nested loops. Please advice.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Get_B_Coordinates(int S, int i, int j, int & K, int & L)
{
    int d = (int) floor(S / 2);
    // new index in bigger array
    K = i + d;  
    L = j + d;
}
void Get_Region(int **padded, int S, int i, int j, int **R, int *V)
{
    int K = 0, L = 0, d = (int) floor(S / 2);
    Get_B_Coordinates(S, i, j, K, L);
    int SR = K - d, ER = K + d;  // index of start and end row
    int SC = L - d, EC = L + d; // index of start and end column

    for (int ip = SR, ir = 0; ip <= ER && ir < S; ip++, ir++)
    {
        for (int jp = SC, jr = 0; jp <= EC && jr < S; jp++, jr++)
        {
            R[ir][jr] = padded[ip][jp];
        }
    }
}
Last edited on
How much larger is the 'padded'?
d = floor (S/2), then padded will have (N+2d) rows and (M+2d) columns, where N,M are the dimension of the original 2-D array to be padded with zeros. (e.g. for S = 3, padded will be of size (N+2) by (M+2), i.e. padding around original array by 1 row and one column).
Last edited on
If I’ve understood your request, perhaps you could try something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <cmath>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <numeric>


using rows_cols = std::pair<int, int>;

void displayCStyleArray(const int* const arr, const rows_cols& dims);
int copyCStyleArraysRegion(const int* const from, const rows_cols& f_dims,
                           const rows_cols& start_el,
                           int* const to, const rows_cols& t_dims,
                           const rows_cols& stretch);



int main()
{
    // Is this big enough?
    constexpr int Max_Rows { 12 };
    constexpr int Max_Cols { 10 };

    int bigger_arr[Max_Rows * Max_Cols];

    std::iota(std::begin(bigger_arr), std::end(bigger_arr), 1);

    std::cout << "Bigger array:\n";
    displayCStyleArray(bigger_arr, { Max_Rows, Max_Cols } );

    rows_cols start_el { 3, 2 };  // 3, 2 --> no meaning, just for test
    rows_cols stretch { 4, 5 };   // 4, 5 --> no meaning, just for test

    int* smaller_arr = new int [stretch.first * stretch.second] {};

    std::cout << "\nSmaller array (before):\n";
    displayCStyleArray(smaller_arr, stretch);

    int copied {
        copyCStyleArraysRegion(bigger_arr, { Max_Rows, Max_Cols },
                               start_el,
                               smaller_arr, stretch,
                               stretch)
    };

    std::cout << "\nSmaller array after:\n";
    displayCStyleArray(smaller_arr, stretch);

    std::cout << "\nTotal element copied: " << copied << '\n';

    delete smaller_arr;
    smaller_arr = nullptr;
}


void displayCStyleArray(const int* const arr, const rows_cols& dims)
{
    for (int i {}; i < dims.first; ++i) {
        for (int j {}; j < dims.second; ++j) {
            std::cout << std::setw(4) << arr[i * dims.second + j];
        }
        std::cout << '\n';
    }
}


int copyCStyleArraysRegion(const int* const from, const rows_cols& f_dims,
                           const rows_cols& start_el,
                           int* const to, const rows_cols& t_dims,
                           const rows_cols& stretch)
{
    if (    start_el.first  + stretch.first  >= f_dims.first
         || start_el.second + stretch.second >= f_dims.second
         || t_dims.first  > stretch.first
         || t_dims.second > stretch.second )
    {
        return 0;
    }

    int counter {};
    const int* start = &from[start_el.first * f_dims.second + start_el.second];
    for (int i {}; i < stretch.first; ++i) {
        for (int j {}; j < stretch.second; ++j) {
            to[i * stretch.second + j] = start[i * f_dims.second + j];
            ++counter;
        }
    }
    return counter;
}


Output:
Bigger array:
   1   2   3   4   5   6   7   8   9  10
  11  12  13  14  15  16  17  18  19  20
  21  22  23  24  25  26  27  28  29  30
  31  32  33  34  35  36  37  38  39  40
  41  42  43  44  45  46  47  48  49  50
  51  52  53  54  55  56  57  58  59  60
  61  62  63  64  65  66  67  68  69  70
  71  72  73  74  75  76  77  78  79  80
  81  82  83  84  85  86  87  88  89  90
  91  92  93  94  95  96  97  98  99 100
 101 102 103 104 105 106 107 108 109 110
 111 112 113 114 115 116 117 118 119 120

Smaller array (before):
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0

Smaller array after:
  33  34  35  36  37
  43  44  45  46  47
  53  54  55  56  57
  63  64  65  66  67

Total element copied: 20

I don’t guarantee it works, anyway: you’d better test it a lot. I usually avoid those kind of math-style codes.
I've made a testing environment for Joo's function. There I got no seg_fault at testing, but I have not tested all possibilities.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <cmath>
#include <iostream>
#include <iomanip>
using namespace std;

void Get_B_Coordinates(int S, int i, int j, int & K, int & L)
{
    int d = (int) floor(S / 2);
    // new index in bigger array
    K = i + d;  
    L = j + d;
}
void Get_Region(int **padded, int S, int i, int j, int **R, int *V)
{
    int K = 0, L = 0, d = (int) floor(S / 2);
    Get_B_Coordinates(S, i, j, K, L);
    int SR = K - d, ER = K + d;  // index of start and end row
    int SC = L - d, EC = L + d; // index of start and end column

    for (int ip = SR, ir = 0; ip <= ER && ir < S; ip++, ir++)
    {
        for (int jp = SC, jr = 0; jp <= EC && jr < S; jp++, jr++)
        {
            R[ir][jr] = padded[ip][jp];
        }
    }
}

int main()
{
   
   // initializing memory for 'padded' and 'R'
   //
     constexpr int S_PADDED = 0x10; // size of 'padded'    
     constexpr int S_R      = 10;   // size of 'R'   
      
     int ** padded = new int* [S_PADDED];     
     for (int i = 0; i < S_PADDED; ++i)
         padded[i] = new int[S_PADDED];   
     for (int i = 0; i < S_PADDED; ++i)
         for( int j = 0; j < S_PADDED; ++j)
             padded[i][j] = i*S_PADDED + j;
                                     
     int ** R = new int* [S_R];
     for (int i = 0; i < S_R; ++i)
         R[i] = new int[S_R];
     for (int i = 0; i < S_R; ++i)
         for (int j = 0; j < S_R; ++j)
             R[i][j] = 0;
 
             
  // testing your function
  //
    int S = 9;
    int i = 7, j = 9;        
    Get_Region( padded, S, i, j, R, nullptr);
    
             
   // printing 'padded' and 'R' on screen 
   //
     std::cout << "'padded':\n";       
     for (int i = 0; i < S_PADDED; ++i) {
         for( int j = 0; j < S_PADDED; ++j)
             std::cout << std::setw(3) << std::hex << padded[i][j];
         std::cout << std::endl;
     }
     std::cout << "\n'R':\n";
     for (int i = 0; i < S_R; ++i) {
         for (int j = 0; j < S_R; ++j)
             std::cout << std::setw(3) << R[i][j];
         std::cout << std::endl;
     }
     
   // deleting allocated memory
   //
     for ( int i = 0; i < S_R; ++i) delete[] R[i];
     delete[] R;
     for( int i = 0; i < S_PADDED; ++i) delete[] padded[i];
     delete[] padded;
}
Topic archived. No new replies allowed.