二维矩阵崩溃的动态重新分配
Dynamic deallocation of a 2D matrix crashing
我有一个在开始时分配 2D 矩阵的函数和一个在最后使用的取消分配它的函数。
int** CreatMat(int N){
int i,**T;
T = (int**)malloc(sizeof(int*)*N);
if(T!=NULL){
for(i=0;i<N;i++){
T[i]=(int*)malloc(sizeof(int)*N);
if(T[i]==NULL){
printf("\nCreatMat()::Allocation failed at block %d",i);
for(i=i;i>=0;i--){
free(T[i]);
T[i]=NULL;
}
free(T);
T=NULL;
return T;
}
}
}
return T;
}
//Free a dynamic matrix.
void FreeMat(int** T,int N){
int i;
for(i=0;i<N;i++){
free(T[i]);
T[i]=NULL;
}
free(T);
T = NULL;
}
不知何故,FreeMat()
崩溃了。有帮助吗?
完整代码here
~janky 修复代码 here
在函数中main()
这个
int **T, **S;
if(Grids_Init(T, S) != 0)
不影响未初始化的局部变量S
和T
的值,然后你继续释放这些不确定的指针。
您可以使用一个函数来初始化其中之一,return 指针并将其分配给 T
。然后 S
.
同样
这比使用三星级指针更可取:请参阅 Triple pointers in C: is it a matter of style? 一个答案以
开头
Using triple pointers is harming both readability and maintainability.
您创建的不是二维数组,而是一个指针数组。让您的生活更轻松,找到真正的 2D 阵列。此外,使用正确的尺寸类型 size_t
void CreatMat(size_t N, int (**array)[N])
{
*array = malloc(N * sizeof(**array));
}
int main(void)
{
int (*array)[N];
CreatMat(1000, &array);
/* some code */
free(array);
}
看看它有多简单。
回应@0_______
#include <stdlib.h>
int main(){
int i,j;
int (*T)[7];
//(*T)[7] = malloc(7*sizeof(&(*T))); is wrong
T = malloc(7*sizeof(*T));
for(i=0;i<7;i++){
printf("\n");
for(j=0;j<7;j++){
printf("%d ");
}
}
free(T);
return 0;
}
- 将矩阵表示为指针数组不是最优的:它浪费内存和时间,而且引用的局部性会更差
- 一旦您认为您需要的不仅仅是双指针,您应该重新考虑您的数据:使用某种结构来表示矩阵。
一个简单的例子:
#include <stdlib.h>
struct matrix {
unsigned nrow;
unsigned ncol;
// int flags;
double *data;
};
/*****************************************************************/
static size_t nrc2idx(unsigned ncol, unsigned irow, unsigned icol)
{
return (irow*ncol) + icol;
}
struct matrix *matrix_new(unsigned nrow, unsigned ncol)
{
struct matrix *mp;
mp = malloc (sizeof *mp);
if (!mp) return mp;
mp->data = malloc (sizeof *mp->data * nrow * ncol);
if ( !mp->data) {
free (mp);
return NULL;
}
mp->nrow = nrow;
mp->ncol = ncol;
return mp;
}
现在,使用这种结构将两个矩阵相乘有多难?
示例代码:
struct matrix *matrix_mult(struct matrix *left, struct matrix *right)
{
struct matrix *result;
unsigned ii,jj;
if (!left || !right) return NULL;
if (left->ncol != right->nrow) return NULL;
result = matrix_new(left->nrow, right->ncol);
if (!result) return NULL;
for (ii=0; ii < result->nrow; ii++) {
for (jj=0; jj < result->ncol; jj++) {
size_t uu;
unsigned kk;
double sum ;
sum = 0.0;
for (kk=0; kk < left->ncol; kk++) {
size_t aa, bb;
aa = nrc2idx(left->ncol, ii, kk);
bb = nrc2idx(right->ncol, kk, jj);
sum += left->data[aa] * right->data[bb];
}
uu = nrc2idx(result->ncol, ii, jj);
result->data[uu] = sum;
}
}
return result;
}
我有一个在开始时分配 2D 矩阵的函数和一个在最后使用的取消分配它的函数。
int** CreatMat(int N){
int i,**T;
T = (int**)malloc(sizeof(int*)*N);
if(T!=NULL){
for(i=0;i<N;i++){
T[i]=(int*)malloc(sizeof(int)*N);
if(T[i]==NULL){
printf("\nCreatMat()::Allocation failed at block %d",i);
for(i=i;i>=0;i--){
free(T[i]);
T[i]=NULL;
}
free(T);
T=NULL;
return T;
}
}
}
return T;
}
//Free a dynamic matrix.
void FreeMat(int** T,int N){
int i;
for(i=0;i<N;i++){
free(T[i]);
T[i]=NULL;
}
free(T);
T = NULL;
}
不知何故,FreeMat()
崩溃了。有帮助吗?
完整代码here
~janky 修复代码 here
在函数中main()
这个
int **T, **S;
if(Grids_Init(T, S) != 0)
不影响未初始化的局部变量S
和T
的值,然后你继续释放这些不确定的指针。
您可以使用一个函数来初始化其中之一,return 指针并将其分配给 T
。然后 S
.
这比使用三星级指针更可取:请参阅 Triple pointers in C: is it a matter of style? 一个答案以
开头Using triple pointers is harming both readability and maintainability.
您创建的不是二维数组,而是一个指针数组。让您的生活更轻松,找到真正的 2D 阵列。此外,使用正确的尺寸类型 size_t
void CreatMat(size_t N, int (**array)[N])
{
*array = malloc(N * sizeof(**array));
}
int main(void)
{
int (*array)[N];
CreatMat(1000, &array);
/* some code */
free(array);
}
看看它有多简单。
回应@0_______
#include <stdlib.h>
int main(){
int i,j;
int (*T)[7];
//(*T)[7] = malloc(7*sizeof(&(*T))); is wrong
T = malloc(7*sizeof(*T));
for(i=0;i<7;i++){
printf("\n");
for(j=0;j<7;j++){
printf("%d ");
}
}
free(T);
return 0;
}
- 将矩阵表示为指针数组不是最优的:它浪费内存和时间,而且引用的局部性会更差
- 一旦您认为您需要的不仅仅是双指针,您应该重新考虑您的数据:使用某种结构来表示矩阵。
一个简单的例子:
#include <stdlib.h>
struct matrix {
unsigned nrow;
unsigned ncol;
// int flags;
double *data;
};
/*****************************************************************/
static size_t nrc2idx(unsigned ncol, unsigned irow, unsigned icol)
{
return (irow*ncol) + icol;
}
struct matrix *matrix_new(unsigned nrow, unsigned ncol)
{
struct matrix *mp;
mp = malloc (sizeof *mp);
if (!mp) return mp;
mp->data = malloc (sizeof *mp->data * nrow * ncol);
if ( !mp->data) {
free (mp);
return NULL;
}
mp->nrow = nrow;
mp->ncol = ncol;
return mp;
}
现在,使用这种结构将两个矩阵相乘有多难? 示例代码:
struct matrix *matrix_mult(struct matrix *left, struct matrix *right)
{
struct matrix *result;
unsigned ii,jj;
if (!left || !right) return NULL;
if (left->ncol != right->nrow) return NULL;
result = matrix_new(left->nrow, right->ncol);
if (!result) return NULL;
for (ii=0; ii < result->nrow; ii++) {
for (jj=0; jj < result->ncol; jj++) {
size_t uu;
unsigned kk;
double sum ;
sum = 0.0;
for (kk=0; kk < left->ncol; kk++) {
size_t aa, bb;
aa = nrc2idx(left->ncol, ii, kk);
bb = nrc2idx(right->ncol, kk, jj);
sum += left->data[aa] * right->data[bb];
}
uu = nrc2idx(result->ncol, ii, jj);
result->data[uu] = sum;
}
}
return result;
}