Home > Software engineering >  Move element at the end of a space of memory allocated with malloc
Move element at the end of a space of memory allocated with malloc

Time:11-26

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;
}
  • Related