Two-dimensional dynamic array pointer access - arrays

p = (int *)malloc(m * n * sizeof(int));
If I use p as a two-dimensional dynamic array, how do I access the elements inside?

If you can rely on your C implementation to support variable-length arrays (an optional feature), then a pretty good way would be to declare p as a pointer to (variable-length) array instead of a pointer to int:
int (*p)[n] = malloc(m * sizeof(*p)); // m rows, n columns
Then you access elements using ordinary double indexes, just as if you had declared an ordinary 2D array:
p[0][0] = 1;
p[m-1][n-1] = 42;
int q = p[2][1];
Most widely used C implementations do support VLAs, but Microsoft's is a notable exception.

I'd personally prefer using wohlstad's method, but you could also variably-modified types, which are an optional feature of C11, but will probably be mandated in C2x:
int (*p)[m] = malloc(n * sizeof *p);
This can now be used just like a normal 2d array with automatic storage duration.
int n = 12, m = 9;
int (*p)[m] = malloc(n * sizeof *p);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
p[i][j] = i * m + j;
printf("%d\n", p[4][2]);
free(p);

I'll assume m is the number of columns, and n the number of rows (you can use n instead of m in my answer if it's the opposite).
In order to access the 2D array, you need 2 indices - let's call them x and y:
x index will be in the range 0 .. m-1, and
y index will be in the range 0 .. n-1
You can calculate the index for your p array in the following way:
int p_idx = y * m + x
Then you can access your arrays element e.g. this way:
p[p_idx] = 111; // set an element value
int a = p[p_idx]; // get an element value

You can't use p as a two-dimensional array. It's a single integer pointer. Two-dimensional (dynamically allocated) implies nested pointers. However, you can represent a two-dimensional array in a "flattened" form. Here's some code that might offer a helpful explanation:
#include <stdio.h>
#include <stdlib.h>
int main(){
// Populating a 10x5 matrix
int m = 10;
int n = 5;
int* p = (int*) malloc(m*n*sizeof(int));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// Each row has n elements; to get the
// "flattened" index, treating the MxN
// matrix as row-major ordered (reading
// left-to-right, and THEN down the rows):
int flattened_index = (i * n) + j;
// E.g., populate with multiplication table data
p[flattened_index] = (i + 1) * (j + 1);
printf("%d\t", p[flattened_index]);
}
printf("\n");
}
// Inversely, to convert a flattened index to a
// row and column, you have to use modulus
// arithmetic
int flattened_index = 21;
int row = flattened_index / n; // Rounded-down integer division
int column = flattened_index % n; // Remainder after division
printf("%d * %d = %d\n", row + 1, column + 1, p[flattened_index]);
return 0;
}
This outputs:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
6 12 18 24 30
7 14 21 28 35
8 16 24 32 40
9 18 27 36 45
10 20 30 40 50
5 * 2 = 10

You are actually creating a single-dimensional array. But still, we can use it to hold a matrix considering the fact in C a multidimensional array, e.g int mat[m][n], is stored in contiguous memory itself.
#include <iostream>
int main()
{
int m, n;
std::cin >> m >> n;
int* mat_ptr = (int*)malloc(m * n * sizeof(int));
if (mat_ptr)
{
for (int row = 0; row < m; ++row)
{
for (int col = 0; col < n; ++col)
{
*(mat_ptr + ((row * n) + col)) = (row * n) + col;
}
}
for (int row = 0; row < m; ++row)
{
for (int col = 0; col < n; ++col)
{
std::cout << *(mat_ptr + ((row * n) + col)) << " ";
}
std::cout << std::endl;
}
}
return 0;
}

Related

Divide an array into subarrays so that sum of product of their length and XOR is minimum

We have an array of "n" numbers. We need to divide it in M subarray such that the cost is minimum.
Cost = (XOR of subarray) X ( length of subarray )
Eg:
array = [11,11,11,24,26,100]
M = 3
OUTPUT => 119
Explanation:
Dividing into subarrays as = > [11] , [11,11,24,26] , [100]
As 11*1 + (11^11^24^26)*4 + 100*1 => 119 is minimum value.
Eg2: array = [12,12]
M = 1
output: 0
As [12,12] one way and (12^12)*2 = 0.
You can solve this problem by using dynamic programming.
Let's define dp[i][j]: the minimum cost for solving this problem when you only have the first i elements of the array and you want to split (partition) them into j subarrays.
dp[i][j] = cost of the last subarray plus cost of the partitioning of the other part of the given array into j-1 subarrays
This is my solution which runs in O(m * n^2):
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000 + 10;
const int MAXM = 1000 + 10;
const long long INF = 1e18 + 10;
int n, m, a[MAXN];
long long dp[MAXN][MAXM];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
// start of initialization
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
dp[i][j] = INF;
dp[0][0] = 0;
// end of initialization
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int last_subarray_xor = 0, last_subarray_length = 0;
for (int k = i; k >= 1; k--) {
last_subarray_xor ^= a[k];
last_subarray_length = i - k + 1;
dp[i][j] = min(dp[i][j], dp[k - 1][j - 1] + (long long)last_subarray_xor * (long long)last_subarray_length);
}
}
}
cout << dp[n][m] << endl;
return 0;
}
Sample input:
6 3
11 11 11 24 26 100
Sample output:
119
One of the most simple classic dynamic programming problems is called "0-1 Knapsack" that's available on Wikipedia.

Swap columns using pointers in C

I am really stucked on this problem, my C code has worked very well using multidimensional arrays but i need to do the same using pointers but i'll describe the problem first.
Having the following matrix, i will get a number which will be the number of permutations (the number of swapping of columns that will move to the right and the last column will move to the first column).
For example
The number of column's permutations: 5
| 1 2 3 | -----> | 2 3 1 |
| 3 1 2 | -----> | 1 2 3 |
| 2 3 1 | -----> | 3 1 2 |
I wrote the following code using pointers, as you can see i build the matrix with multidimensional array and assign all of it into a pointer:
short elementMatrix[3][3] = {{1, 2, 3},
{3, 1, 2},
{2, 3, 1}};
short *element_matrix;
element_matrix = *elementMatrix;
int counter = 1;
while (counter <= 5)
{
for (int i = 0; i < 3; i++)
{
int temp = elementMatrix[i][PR.elem_mat_size - 1];
*outElementMatrix = *outElementMatrix + i * PR.elem_mat_size + PR.elem_mat_size - 1;
for (int j = 3 - 1; j >= 0; j--)
{
*(outElementMatrix + i * PR.elem_mat_size + j) = *(outElementMatrix + i * PR.elem_mat_size + j - 1);
if (j == 0)
{
*(outElementMatrix + i * PR.elem_mat_size + j) = *outElementMatrix;
}
}
}
counter++;
}
Since you want to swap out columns, it makes sense to have the pointers represent the columns. That way, you can swap a pointer to swap a column. So let's have an array of 3 pointers to a column.
short* col[3];
Each column consists of 3 shorts, so allocate that much memory.
for (int i = 0; i < 3; i++) {
col[i] = (short*)malloc(3 * sizeof(short));
}
Now to initialize the Matrix. This is a bit verbose, so if anyone knows a better way, edit away. :)
col[0][0] = 1; col[1][0] = 2; col[2][0] = 3;
col[0][1] = 3; col[1][1] = 1; col[2][1] = 2;
col[0][2] = 2; col[1][2] = 3; col[2][2] = 1;
Now we do the swap. Note how you need a temp variable, like Rishikesh Raje suggested. Also note that three swaps bring it back to the original, so instead of swapping n times, you only have to swap n % 3 times. Of course it's going to be pretty much instant with 5 or 2 swaps, but if you have to do like a billion, the difference should be noticeable.
for (int i = 0; i < 5; i++) {
short* temp = col[2];
col[2] = col[1];
col[1] = col[0];
col[0] = temp;
}
We assure that the result is correct by printing it:
for (int i = 0; i < 3; i++) {
printf("%d %d %d\n", col[0][i], col[1][i], col[2][i]);
}
You can consider the permutations as a rotation of each row in the matrix and, unless you have to somehow use the matrix after each step, calculate only the final result.
I'll use an extra buffer to help with the swaps.
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
// rotate the values of an array using a buffer to ease the swappings
void rotate_(size_t n, void *arr, void *tmp, size_t offset)
{
assert(n && arr && tmp && offset <= n);
// casting to perform pointer arithmetic
memcpy(tmp, (char *)arr + (n - offset), offset);
memmove((char *)arr + offset, arr, n - offset);
memcpy(arr, tmp, offset);
}
void rotate_columns_short(size_t r, size_t c, short mat[r][c], short *buf, int n)
{
// clamp the value of the offset to the number of columns
size_t offset = (n >= 0
? n % c
: c - -n % c) * sizeof(short);
// transform each row
for (short *row = &mat[0][0], *row_end = row + r * c;
row != row_end;
row += c)
{
rotate_(c * sizeof(short), row, buf, offset);
}
}
void print_matrix_short(size_t r, size_t c, short mat[r][c])
{
for (size_t i = 0; i < r; ++i)
{
for (size_t j = 0; j < c; ++j)
{
printf(" %hd", mat[i][j]);
}
puts("");
}
}
#define ROWS 3
#define COLS 3
int main(void)
{
short matrix[ROWS][COLS] = {{1, 2, 3},
{3, 1, 2},
{2, 3, 1}};
short buf[COLS];
print_matrix_short(ROWS, COLS, matrix);
puts("");
rotate_columns_short(ROWS, COLS, matrix, buf, 5);
print_matrix_short(ROWS, COLS, matrix);
}
The output beeing:
1 2 3
3 1 2
2 3 1
2 3 1
1 2 3
3 1 2

Swap sub-arrays of a multi-dimensional array in C

I have a 50 x 50 matrix arr[50][50] and need to swap the values in the sub-array arr[0] and arr[1].
ie, the whole 50 elements in each sub-array need to be swapped.
The only way I can think of to do this is by using a loop like:
for(i=0; i<50; ++i)
{
int t = arr[0][i];
arr[0][i] = arr[1][i];
arr[1][i] = t;
}
I was wondering if there were any simpler or shorter methods? Using pointers maybe?
I tried things like
int *t = arr[0];
arr[0] = arr[1];
arr[1] = t;
but it gave error at the first line about "incompatible types when assigning to type 'int[2]' from type 'int *' ".
Then I tried pointer to an array
int (*t)[50] = arr[0];
arr[0] = arr[1];
arr[1] = t;
This time I got error at the second line about "incompatible types when assigning to type 'int[50]' from type 'int *' ".
If your matrix is implemented as arr[50][50] then the only way to physically swap two rows is to physically exchange data in memory. Your cycle is one way to do it. The rest would be just variations of that approach. You can swap matrix elements one-by-one (your cycle), you can swap the entire rows using an intermediate row-sized buffer (memcpy approach). All of them still do the same thing. There's no way around it.
If your array were implemented differently - say, a "jagged" array implemented as array of pointers to sub-arrays, then you would be able to just swap two pointers and be done with it. But in case of arr[50][50] it is not possible.
If you wish, you can just "convert" your current array into a "jagged" version by a separate row-pointer array. That row-pointer array will now become your matrix a, while the original a[50][50] will become a_data
int a_data[50][50];
int *a[50];
for (unsigned i = 0; i < 50; ++i)
a[i] = a_data[i];
/* Fill the matrix */
for (unsigned i = 0; i < 50; ++i)
for (unsigned j = 0; j < 50; ++j)
a[i][j] = rand();
/* Print the matrix */
for (unsigned i = 0; i < 50; ++i)
{
for (unsigned j = 0; j < 50; ++j)
printf("%d ", a[i][j]);
printf("\n");
}
/* Swap the rows */
int *temp = a[0];
a[0] = a[1];
a[1] = temp;
/* Print the matrix */
for (unsigned i = 0; i < 50; ++i)
{
for (unsigned j = 0; j < 50; ++j)
printf("%d ", a[i][j]);
printf("\n");
}
Note, that despite the physical structure of a is now different, you can still use a[i][j] syntax to work with it.
As explained in the comments, and within the other answers, in order to swap rows of an actual 2D array (as apposed to an array of pointers), you must copy/move the data from the source to target row in memory. The most straight forward way to approach this is either with a loop to copy element-by-element to temporary storage to effect the swap, or use the memory copy functions provided by the C-library (e.g. memcpy or memmove). A simple implementation using memcopy (shown with a 3x10 array for array for purposes of the example) would be:
#include <stdio.h>
#include <string.h>
enum { ROW = 3, COL = 10 };
void swaprow (int (*a)[COL], int c1, int c2);
void prna (int (*a)[COL]);
int main (void) {
int a[ROW][COL] = {{0}};
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COL; j++)
a[i][j] = i;
prna (a);
swaprow (a, 0, 1);
putchar ('\n');
prna (a);
return 0;
}
void swaprow (int (*a)[COL], int c1, int c2)
{
int tmp[COL];
memcpy (tmp, a[c1], COL * sizeof *tmp);
memcpy (a[c1], a[c2], COL * sizeof *a[c1]);
memcpy (a[c2], tmp, COL * sizeof *a[c2]);
}
void prna (int (*a)[COL])
{
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++)
printf ("%2d", a[i][j]);
putchar ('\n');
}
}
Example Use/Output
$ ./bin/array2d_swap_row
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0
2 2 2 2 2 2 2 2 2 2
Look things over and let me know if you have any questions.
You will have to copy the data to be swapped with memcpy, I have provided sample to program to show how you can do it(ie swap arr[0] and arr[1]).
int main(void) {
// your code goes here
int t[3];
int arr[3][3]={{1,2,3},{4,5,6},{7,8,9}};
printf("\n%d %d %d",arr[0][0],arr[0][1],arr[0][2]);
printf("\n%d %d %d",arr[1][0],arr[1][1],arr[1][2]);
memcpy(t,arr[0],sizeof(t));
memcpy(arr[0],arr[1],sizeof(t));
memcpy(arr[1],t,sizeof(t));
printf("\n%d %d %d",arr[0][0],arr[0][1],arr[0][2]);
printf("\n%d %d %d",arr[1][0],arr[1][1],arr[1][2]);
return 0;
}

2D array as contiguous block of memory

I know this question was answered but it somehow doesn't work for me.
I dynamically allocate memory for array like this:
arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*columns*sizeof(int))); // <-- THIS DOESN'T WORK
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
//arr[row] = (int*)(malloc(columns*sizeof(int))); <---THIS WORKS
arr[row][col] = num;
printf("%d ", arr[row][col]);
if((++col == columns)){
row++;
col = 0;
printf("\n");
}
}
It throws segmentation fault after 4th row, if matrix is 6x6.
Any advice? Thanks
EDIT:
See: http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/ point number 4. If I do it like in point 3, it works. But I need it like in 4.
There exists no case where you should use fragmented malloc calls like you do. It is wide-spread but bad and incorrect practice. As you point out, it will not give you a true 2D array in adjacent memory, but rather a fragmented, slow mess.
How to do this properly:
In standard C, write
int (*arr)[rows][columns] = malloc (sizeof(*arr));
(*arr)[r][c] = something;
...
free(arr);
or if you prefer to use syntax which is easier-to-read (but perhaps harder to understand):
int (*arr)[columns] = malloc (sizeof(int[rows][columns]));
arr[r][c] = something;
...
free(arr);
In obsolete versions of C, you will have to write a "mangled array":
int* arr = malloc(rows * columns * sizeof(*arr));
arr[r*c] = something;
...
free(arr);
To allocate a contiguous memory, you'll have to use
arr = malloc(sizeof(int *) * rows);
arrayData = malloc(sizeof(int) * columns * rows);
for(i = 0; i < rows; i++)
arr[i] = arrayData + i * columns ;
To deallocate you'll need to have
free( arrData );
free( arr );
See here
You need to allocate memory for each row, not just the first row. Replace
arr[0] = (int*)(malloc(rows*columns*sizeof(int)));
with
for(int i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
The changes made here are:
All the rows will be allocated columns * sizeof(int) bytes of memory.
Casting the result of malloc is pointless in C. I've removed it.
You might need to add a check in the loop to prevent an overflow. Something like
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
The fixed code would be
int i, row = 0, col = 0;
int rows = 6, columns = 6; /* For 6x6 matrix */
arr = malloc(rows * sizeof(int*));
for(i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
arr[row][col] = num;
printf("%d ", arr[row][col]);
if(++col == columns){
row++;
col = 0;
printf("\n");
}
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
}
For a 6x6 matrix, dynamic memory is overkill. You should simply use:
int arr[rows][cols];
This is much simpler, cleaner, quicker, less error prone and generally all round safer — as long as you keep the matrix size small enough that it easily fits on the stack. If you need a large matrix (say from 1 MiB upwards, but you'll need to tune your threshold to suit your systems), then dynamic memory is relevant.
You can make the single allocation to arr[0] work, but you have to do explicit assignments to each of arr[1] through arr[5]. I did it this way:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int rows = 6;
int cols = 6;
int **arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*cols*sizeof(int)));
for (int i = 1; i < rows; i++)
arr[i] = arr[i-1] + cols;
printf("\nArray: \n");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
arr[i][j] = (i+1) * (cols + 1 - j);
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%3d", arr[i][j]);
putchar('\n');
}
free(arr[0]);
free(arr);
return(0);
}
Sample output:
Array:
7 6 5 4 3 2
14 12 10 8 6 4
21 18 15 12 9 6
28 24 20 16 12 8
35 30 25 20 15 10
42 36 30 24 18 12
Running valgrind gives a clean bill of health.

C - Read matrix of unknown size from file

I have file that has 30 matrices and each matrix has unknown size of rows and columns(with a max size of 1000). For instance:
0 5 2
5 0 2
1 6 0
0 9 7 4
3 0 9 1
9 1 0 4
9 4 1 0
I need to read each matrix into a 2d array. What would be the most efficient way of doing this?
This is what I have so far:
int** mat=malloc(1000000*sizeof(int*));
for(i=0;i<1000000;++i)
mat[i]=malloc(4*sizeof(int));
while(!feof(file))
{
for(i=0;i<1000;i++)
{
for(j=0;j<1000;j++){
fscanf(file,"%d%*[^\n]%*c",&mat[i][j]);
printf("%d\n", mat[i][j]);
}
}
}
Well the most efficient way is definitely not that. First figure out how big an array you need, then allocate it.
Apparently some matrices are small, so there is no need to allocate the maximum size 1000x1000. One way is to put the matrix in a structure to make it easier to keep track of size:
struct s_matrix
{
int **matrix;
int N; //one side of the square matrix N x N
};
typedef struct s_matrix Matrix;
Then allocate and free the matrix
void allocate_matrix(Matrix *m, int N)
{
m->N = N;
m->matrix = (int**)malloc(N * sizeof(int*));
*m->matrix = (int*)malloc(N * N * sizeof(int));
for (int i = 0; i < N; i++)
m->matrix[i] = *m->matrix + i * N;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
m->matrix[i][j] = 0;
}
void free_matrix(Matrix *m)
{
if (!m) return;
if (!m->matrix) return;
free(*m->matrix);
free(m->matrix);
}
Now we can declare how many matrices we need. It looks like this number is fixed at 30, so I don't think we need dynamic allocation.
int main()
{
const int max_count = 30;
Matrix list[max_count];
for (int i = 0; i < max_count; i++)
list[i].matrix = NULL;
allocate_matrix(&list[0], 3);//allocate 3x3 matrix
allocate_matrix(&list[1], 1000);//1000x1000
allocate_matrix(&list[2], 4000);//4000x4000
int **m;
m = list[0].matrix;
m[0][0] = 0;
m[0][1] = 1;
m[0][2] = 2;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
printf("%02d %s", m[i][j], (j == 2) ? "\n" : "");
//...
for (int i = 0; i < max_count; i++)
free_matrix(&list[i]);
printf("hey it worked, or maybe it didn't, or it did but there is memory leak\n");
return 0;
}

Resources