简体   繁体   中英

dynamic matrix initialization error

I got an error assignment makes pointer from integer without a cast while trying to initialize a dynamic matrix using this function:

int** allocate_matrix_solid(int n, int m)
{
    int **data = malloc(n * sizeof(int*) +n * m * sizeof(int));
    if (!data)
    return NULL;
    for (int i = 0; i < n; i++)
        data[i] = (int*)((char*) data + n * sizeof(int*) + i * m * sizeof(int));
    return data;
}


int** data = allocate_matrix_solid(2,2);

Where could there be the mistake?

You can't allocate and simulate a 2D array (aka matrix) that way and have it do anything but be 100% non-portable between 32-bit and 64-bit machines. Why?

With int **data = malloc(n * sizeof(int*) +n * m * sizeof(int)); you allocate n-pointers + n * m integers which effectively allocates n + n * m pointers on a 32-bit box and n + (n * m)/2 pointers on a 64-bit box. While you are getting creative attempting to index data[i] = (int*)((char*) data + n * sizeof(int*) + i * m * sizeof(int)); , it is a recipe for disaster and likely breaks pointer-arithmetic.

Simulating a 2D array where n and m are unknown at compile time is a 2-step process. First you allocate/validate storage for n-pointers and then allocate/validate storage for m-integers assigning the beginning address in each new block to your data[i] . If m is a constant, then you can allocate using a pointer-to-array-of-type [] and allocate at once with n * m * sizeof (type) , but you do not have int (*data)[2] you have int **data which are two fundamentally different types requiring two different approaches to allocation.

If you want to simulate the 2D array (matrix) and allocate storage for pointers and data, you will do something similar to:

#include <stdio.h>
#include <stdlib.h>

#define NROW 2
#define NCOL 2

int **allocate_matrix_solid (int n, int m)
{
    int **data = malloc (n * sizeof *data);    /* allocate n pointers */
    if (!data)
        return NULL;
    for (int i = 0; i < n; i++) {
        data[i] = calloc (m, sizeof *data[i]); /* allocate m integers */
        if (!data[i])         /* calloc used to initilize memory zero */
            return NULL;
    }
    return data;
}

int main (void) {

    int **data = allocate_matrix_solid (NROW, NCOL);
    if (!data) {
        fprintf (stderr, "error: allocate_matrix_solid failed.\n");
        return 1;
    }
    for (int i = 0; i < NROW; i++) {    /* output matrix */
        for (int j = 0; j < NCOL; j++)
            printf (" %2d", data[i][j]);
        free (data[i]);                 /* free integers */
        putchar ('\n');
    }
    free (data);                        /* free pointers */
    return 0;
}

Example Use/Output

$ ./bin/allocmatrix
  0  0
  0  0

Look things over and let me know if you have further questions. Typically a "roll-your-own" indexing scheme mixing pointers and data in one big block of memory is just a bad idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM