Setup a 2D array, change size later - C

2020-05-01 09:24发布

问题:

Is it possible to declare a 2D array in C, then set its size later on? I know in C you have to deal with memory and such, but I cannot find answer to this question despite all my searching.

My current example is..

   int boardsize, linewin;
   char array[1][1];
   //boardsize is set within here.

   array = [boardsize][boardsize];

回答1:

With C you will need to do your own dynamic array management using pointers.

See the following articles on how to go about doing so using an allocated memory area.

Malloc a 2D array in C

Using malloc for allocation of multi-dimensional arrays with different row lengths

Since you are looking to modify these, you may also need to use the realloc() function or the free() function to release allocated memory.

For information about using the realloc() function look at the following stack overflow.

Realloc double 2D array in C

two-dimensional dynamic array (realloc in c)

EDIT - Adding an example

Here are two functions to malloc() a two dimensional array and to realloc() a two dimensional array. You could actually just use the realloc() version if you pass a NULL pointer to realloc2dCArray() for the memory area to be reallocated.

What I have tried to do is to use a single malloc() and realloc() for all of the memory needed so that you can free() the memory with a single call to free().

char **malloc2dCArray (int nRows, int nCols)
{
    // use a single malloc for the char pointers to the first char of each row
    // so we allocate space for the pointers and then space for the actual rows.
    char **pArray = malloc (sizeof(char *) * nRows + sizeof(char) * nCols * nRows);

    if (pArray) {
        // calculate offset to the beginning of the actual data space
        char *pOffset = (char *)(pArray + nRows);
        int   i;

        // fix up the pointers to the individual rows
        for (i = 0; i < nRows; i++) {
            pArray[i] = pOffset;
            pOffset += nCols;
        }
    }

    return pArray;
}

char **realloc2dCArray (char **pOld, int nRows, int nCols)
{
    // use a single realloc for the char pointers to the first char of each row
    // so we reallocate space for the pointers and then space for the actual rows.
    char **pArray = realloc (pOld, sizeof(char *) * nRows + sizeof(char) * nCols * nRows);

    if (pArray) {
        // calculate offset to the beginning of the actual data space
        char *pOffset = (char *)(pArray + nRows);
        int   i;

        // fix up the pointers to the individual rows
        for (i = 0; i < nRows; i++) {
            pArray[i] = pOffset;
            pOffset += nCols;
        }
    }

    return pArray;
}

To use these functions you would do something like the following:

char **pChars = malloc2dCArray (16, 8);
int i, j;

for (i = 0; i < 16; i++) {
    for (j = 0; j < 8; j++) {
        pChars[i][j] = 0;
    }
}

To do a realloc() you will want to check that the realloc() worked so use a temporary variable and check for NULL before using it.

{
    char **pChars2 = realloc2dCArray (pChars, 25, 8);
    if (pChars2) pChars = pChars2;
}

You could also just use the realloc() version if you provide a NULL pointer since realloc() will do a malloc() if the pointer to the memory to realloc() is NULL.

I did some testing of this using a debugger and it looks like it is working to me.