Search code examples
cpointersdynamicmultidimensional-arrayrealloc

Reallocating a 2d array if initialized like so: char (*A)[size] = malloc(sizeof(char[size][size]))


char (*A)[size] = malloc(sizeof(char[size][size]));

If I initialize size as 10, but eventually I need more memory, how can I reallocate memory for A without losing its contents?

I tried something like this:

char (*B)[sizeColumns] = realloc(A, sizeof(char[sizeColumns][sizeColumns]));
A = B;

I start running into problems when I need to reallocate.

char linearray[1025];
char *line;
int stars = 0;
int sizeColumns = 4;
int usedColumns = 0;
char (*A)[sizeColumns] = malloc(sizeof(char[sizeColumns][sizeColumns]));
int i;
int j;
int rows = 5;

for(i = 0; i < rows; i++ ){
    if(i==0){
        A[i][0] = '+';
    }
    else{
        A[i][0] = '|';
    }
}
usedColumns++;
while(fgets(linearray,1024,stdin) != NULL){
    line = linearray;
    sscanf(line,"%d", &stars);
    if (usedColumns == sizeColumns) {
        sizeColumns *= 2;
        char (*B)[sizeColumns] = realloc(A, sizeof(char[sizeColumns][sizeColumns]));
        A = B;
    }
    for(i = 0; i < stars +1; i++ ){
        if(i==0){
            A[i][usedColumns] = '-';
        }
        else{
            A[i][usedColumns] = '*';
        }
    }
    usedColumns++;
}

If I input 1,2,3,4 above I want:

+----
|****
| ***
|  **
|   *

which I can successfully output if I initiallize sizeColumns as 5 above, but if it is 4 then I get:

+----
-****
*?***
*  **
*   *

I dont see how the contents of the first column is being overwritten. Again everything works fine if I dont need to reallocate.


Solution

  • My suggestion to separate the histogram display parts so as to use a dynamic array input data array.


    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX_DATA_SIZE 80 //console width is 80 :)
    
    void histogram(int n, int data[n], int max){
        char (*disp)[n+1] = malloc(sizeof(char [max+1][n+1]));//Area for display is actually not required.
        int r,c;
        for(r = 0;r <= max; ++r){
            for(c = 0; c <= n; ++c){
                if(c == 0){
                    if(r == 0)
                        disp[r][c] = '+';
                    else
                        disp[r][c] = '|';
                } else if(r == 0){
                    disp[r][c] = '-';
                } else {
                    disp[r][c] = r <= data[c-1] ? '*' : ' ';
                }
            }
        }
        for(r = max; r>=0;--r){
            for(c =0;c<=n;++c)
                printf("%c", disp[r][c]);
            printf("\n");
        }
    }
    
    int main(void){
        int data[MAX_DATA_SIZE], max_data = 0;
        char input_line[128];
        int data_size = 0;
        while(fgets(input_line, sizeof(input_line), stdin)){
            if(sscanf(input_line, "%d", &data[data_size])==1){
                if(data[data_size] > max_data)
                    max_data = data[data_size];
                if(++data_size == MAX_DATA_SIZE)
                    break;//or malloc & realloc ?
            }
        }
        histogram(data_size, data, max_data);
        return 0;
    }