您已经在堆上分配了二维矩阵,并且您正在使用 aSquare**
来访问它。这意味着您已经:(1)在一次或多次调用中为每个元素分配空间malloc
,以及(2)在调用中为所有行指针分配空间malloc
。如何进行很大程度上取决于您分配数组的方式。
下面,我assert
用来强调每个 malloc/realloc 都可以返回 NULL(表示它无法完成请求)。您可能希望正确处理这些情况。
选项 1:您分别分配每一行
您像这样分配s1
矩阵:
Square** s1 = malloc(M1*sizeof(s1[0]));
for (size_t i=0; i < M1; i++)
s1[i] = malloc(N1*sizeof(s1[i][0]));
在这种情况下,您必须分别处理每一行:
/* M1 and N1 set to size of s1 (M1 x N1) */
/* M2 and N2 set to size of s2 (M2 x N2) */
/* First, reallocate the pointers to each row */
Square** tmpRows = realloc(s1, M2*sizeof(*tmpRows));
assert( (tmpRows != NULL) && "Out of memory reallocating rows" );
s1 = tmpRows;
/* Now, reallocate each row */
for (size_t i=0; i < M1; i++) {
Square* tmpVals = realloc(s1[i], N2*sizeof(tmpVals[0]));
assert( (tmpVals != NULL) && "Out of memory reallocating row" );
/* copy elements of s2 into new column */
memcpy(tmpVals+N1, s2[i]+N1, (N2-N1)*sizeof(s1[i][0]));
s1[i] = tmpVals;
}
/* Now, allocate each new row of s1 and copy the additional rows of s2 into s1 */
for (size_t i=M1; i < M2; i++) {
s1[i] = malloc( N2 * sizeof(s1[i][0]) );
assert( (s1[i] != NULL) && "Out of memory allocating new row" );
memcpy(s1[i], s2[i], N2*sizeof(s1[i][0]));
}
选项 2:您一次分配所有行
在这种情况下,您将所有行分配在一个大块中,然后将指针分配到每一行的开头。像这样:
Square** s1 = malloc(M1*sizeof(s1[0]));
s1[0] = malloc( M1*N1*sizeof(s1[0][0]) );
for(size_t i=1; i < M1; i++)
s1[i] = s1[i-1] + N1;
要调整数组的大小(并使用 s2 的元素初始化其新元素),您应该执行以下操作:
/* M1 and N1 set to size of s1 (M1 x N1) */
/* M2 and N2 set to size of s2 (M2 x N2) */
/* Make a new copy of the elements of s1. Linear layout of a 200x200
* matrix will be different than the linear layout of a 100x100 matrix.
* Making a new copy makes it easier to initialize its values.
*/
Square* new_mat = malloc( M2*N2*sizeof(new_mat[0]) );
assert( (new_mat != NULL) && "Out of memory allocating new matrix" );
/* Initialize with values of s2. Assumption: s2 is also allocated
* as a contiguous array...
*/
memcpy(new_mat, s2[0], M2*N2*sizeof(s2[0][0]));
/* Now, reallocate the rows */
Square** tmpRows = realloc(s1, M2*sizeof(s1[0]));
assert( (tmpRows != NULL) && "Out of memory reallocating rows" );
s1 = tmpRows;
/* Copy data from old rows into new rows... */
for (size_t i=0; i < M1; i++) {
/* rows of s1 still point to old_mat data, copy it into new_mat.
* Each row in new_mat starts at (new_mat + N2*i)
*/
memcpy( new_mat + N2*i, s1[i], N1*sizeof(s1[i][0]) );
}
/* Free old memory and assign new row pointers... */
free(s1[0]);
s1[0] = new_mat;
for (size_t i=1; i < M2; i++)
s1[i] = s1[i-1] + N2;