I allocated a space of memory with malloc (to have a matrix) and I have to move the "row" at the end, I tried this:
double **dataset = fill_dataset(....);
double* temp = malloc((d 1) * sizeof(double ));
for (int i = 0; i < d 1; i ) {
temp[i] = dataset[0][i];
}
memmove(&dataset[0], &dataset[1], (p_in_retained - 1) * sizeof(double *));
for (int i = 0; i < d 1; i ) {
dataset[p_in_retained - 1][i] = temp[i];
}
p_in_retained is the number of rows, the problem is that when the second loop ends I have the same element in the last and the second to last element, for example, suppose that this is the initial matrix:
id col1 col2
1 1 1
2 6 3
3 8 2
4 9 1
what I expect to have is the following:
id col1 col2
2 6 3
3 8 2
4 9 1
1 1 1
what I get is:
id col1 col2
2 6 3
3 8 2
1 1 1
1 1 1
CodePudding user response:
Array od pointers (ie double pointer).
void rotateRow(size_t rows, int **data)
{
int *temp = data[0];
if(rows > 1)
{
for(size_t i = 0; i < rows - 1; i )
data[i] = data[i 1];
data[rows - 1] = temp;
}
}
Real 2D array Use pointers to arrays. It makes it much easier
malloc version:
void rotateRow(size_t rows, size_t cols, int (*array)[cols])
{
int (*temp)[cols] = malloc(sizeof(*temp));
if(temp)
{
memcpy(temp, array[0], sizeof(*array));
memmove(array[0], array[1], sizeof(*array) * (rows - 1));
memcpy(array[rows - 1], temp, sizeof(*array));
}
free(temp);
}
void print(size_t rows, size_t cols, int (*array)[cols])
{
for(size_t r = 0; r < rows; r )
{
for(size_t c = 0; c < cols; c )
printf("%d ", array[r][c]);
printf("\n");
}
}
int main(void)
{
int (*array)[3] = malloc(4 * sizeof(*array));
memcpy(array,
(int [4][3]){{ 1 , 1, 1,},
{2, 6, 3,},
{3, 8, 2,},
{4, 9, 1,},}, sizeof(*array) * 4);
print(4,3,array);
rotateRow(4,3,array);
printf("\n --------- \n");
print(4,3,array);
free(array);
};
void rotateRow(size_t rows, size_t cols, int (*array)[cols])
{
int temp[cols];
memcpy(temp, array[0], sizeof(*array));
memmove(array[0], array[1], sizeof(*array) * (rows - 1));
memcpy(array[rows - 1], temp, sizeof(*array));
}
void print(size_t rows, size_t cols, int (*array)[cols])
{
for(size_t r = 0; r < rows; r )
{
for(size_t c = 0; c < cols; c )
printf("%d ", array[r][c]);
printf("\n");
}
}
int main(void)
{
int array[4][3] = {{ 1 , 1, 1,},
{2, 6, 3,},
{3, 8, 2,},
{4, 9, 1,},};
print(4,3,array);
rotateRow(4,3,array);
printf("\n --------- \n");
print(4,3,array);
};
https://godbolt.org/z/dWMWr5qr3
CodePudding user response:
Your memmove
isn't calculating the correct number of bytes to move. This sample does what you're looking for:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COLS 3
#define ROWS 4
void printDataset(double dataset[ROWS][COLS]) {
printf ("id\tcol1\tcol2\n");
for (int i = 0; i < ROWS; i )
printf("%.0f\t%.0f\t%.0f\n", dataset[i][0], dataset[i][1], dataset[i][2]);
}
int main() {
double dataset[ROWS][COLS] = { {1, 1, 1}, {2, 6, 3}, {3, 8, 2}, {4, 9, 1} };
printDataset(dataset);
double* temp = malloc(COLS * sizeof(double));
for (int i = 0; i < COLS; i )
temp[i] = dataset[0][i];
memmove(&dataset[0], &dataset[1], (ROWS - 1) * COLS * sizeof(double));
for (int i = 0; i < COLS; i )
dataset[ROWS - 1][i] = temp[i];
printDataset(dataset);
free(temp);
return 0;
}
And here's a pure pointer version that doesn't use static arrays except to initialise the dataset buffer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COLS 3
#define ROWS 4
double dataset[ROWS][COLS] = { {1, 1, 1}, {2, 6, 3}, {3, 8, 2}, {4, 9, 1} };
void printDataset(double* dataset, int rows, int cols) {
printf ("id\tcol1\tcol2\n");
for (int i = 0; i < rows; i ) {
for (int j = 0; j < cols; j )
printf("%.0f\t", *(dataset i * cols j));
printf("\n");
}
}
int main() {
double* ds = malloc(ROWS * COLS * sizeof(double));
memcpy(ds, dataset, ROWS * COLS * sizeof(double));
printDataset(ds, ROWS, COLS);
double* temp = malloc(COLS * sizeof(double));
for (int i = 0; i < COLS; i )
temp[i] = *(ds i);;
memmove(ds, ds COLS, (ROWS - 1) * COLS * sizeof(double));
for (int i = 0; i < COLS; i )
*(ds (ROWS - 1) * COLS i) = temp[i];
printDataset(ds, ROWS, COLS);
free(ds);
free(temp);
return 0;
}