c - 局部变量可能指向释放的内存
问题描述
我在标题中有一个结构(ex3.h)
typedef struct matrix {
double **data;
size_t n_rows;
size_t n_columns;
} matrix;
在c文件中,我有函数“create_matrix”和另一个函数切片,我在某些地方收到警告“局部变量可能指向已释放的内存”。我在评论中将它们标记为“--->”
#include <stdlib.h>
# include <stdio.h>
# include "ex3.h"
#define DEBUG
matrix *create_matrix (size_t n_rows, size_t n_columns)
{
matrix *mat = malloc (sizeof (matrix));
if (!mat)
{
fprintf (stderr, POINTER_ERROR);
return NULL;
}
if (n_rows == ZERO || n_columns == ZERO)
{ mat->data = NULL, mat->n_rows = ZERO, mat->n_columns = ZERO; }
else
{
{
double **mat_data = malloc (n_rows * sizeof (double *));
if (!mat_data)
{
free (mat);
fprintf (stderr, POINTER_ERROR);
return NULL;
}
for (int i = ZERO; i < n_rows; i++)
{
mat_data[i] = malloc (n_columns * sizeof (double));
if (!mat_data[i])
{
for (int k = ZERO; k < i; k++)
{
free (mat_data[k]);
}
free (mat_data), free (mat);
fprintf (stderr, POINTER_ERROR);
return NULL;
}
else
{
for (int j = ZERO; j < n_columns; j++)
{
mat_data[i][j] = (double) ZERO;
}
}
}
mat->data = mat_data, mat->n_rows = n_rows, mat->n_columns = n_columns;
}
}
return mat;
}
matrix *slice (matrix *mat, size_t row_start,
size_t row_end, size_t col_start, size_t col_end)
{
"some condions..."
{
matrix *m = create_matrix (ZERO, ZERO); //nul matrix
if (!m) "<---"
{
return NULL;
}
return m; "<---"
}
else
{
size_t row = row_end - row_start, col = col_end - col_start;
matrix *new_mat = create_matrix (row, col);
if (!new_mat)"<---"
{
return NULL;
}
for (int i = ZERO; i < row; i++)
{
for (int j = ZERO; j < col; j++)
{
"--->" (new_mat->data)[i][j] = mat->data[i + row_start][j + col_start];
}
}
return new_mat; "<---"
}
}
我提出了一些条件,以确保我不会尝试去内存空间中不属于我的矩阵的空间,那么为什么 clion 仍然发出警告感谢您的帮助!
解决方案
我会用另一种方式来做。取而代之的是大量的分配,我只会使用一个。我会使用正面测试而不是负面测试(即有什么问题),并且该函数只有一个返回点。
typedef struct matrix {
size_t n_rows;
size_t n_columns;
double data[];
} matrix;
matrix *allocate(size_t r, size_t c)
{
matrix *m = malloc(sizeof(*m) + r * c * sizeof(m -> data[0]));
if(m)
{
m -> n_rows = r;
m -> n_columns = c;
}
return m;
}
matrix *slice(matrix *m, size_t sr, size_t er, size_t sc, size_t ec)
{
matrix *result = NULL;
size_t lc = ec - sc, lr = er - sr;
if(m && m -> n_rows > er && m -> n_rows > sr && sr <= er && m -> n_columns > ec && m -> n_columns > sc && sc <= ec)
{
result = allocate(lr, lc);
if(result)
{
double (*dest)[lc] = &result -> data;
double (*src)[m -> n_columns] = &m -> data;
result -> n_rows = lr;
result -> n_columns = lc;
for(size_t row = 0; row < lr; row ++)
{
memcpy(dest[row], &src[sr + row][sc], lc * sizeof(m -> data[0]));
}
}
}
return result;
}
推荐阅读
- html - 如何在没有 css 文件的情况下为 flexbox div 元素添加响应性
- c++ - 如何从 C++ 中的向量中检查素数?
- c - 大写和小写 printf() 有什么区别
- android - 添加消息后与firebase反应本机崩溃,没有错误,然后在删除可触摸不透明度后不起作用
- batch-file - 如何指定当前目录
- postgresql - Postgresql 通过 psql 还原转储得到“表的权限被拒绝”
- jquery - 如何在 asp.net mvc 5 中使用 jquery ajax 将模型添加到剃须刀页面?
- python - 如何在后台启动子进程并通过按键停止它?
- java - 自动雅虎邮件登录时,密码编辑框上的 Sendkey 命令不起作用
- android - 通过 Activity 更改持久化 RecylerView 适配器