- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试编写一个程序,该程序能够根据运算符偏好等对矩阵表达式进行乘法和加法运算。我完成了程序并且它可以工作,但是完成后我在 valgrind 中遇到了一些错误。很明显,这是因为在指向下一个矩阵的指针附近错误地使用了 free()。但我无法弄清楚如何正确地做到这一点。有人可以帮助我吗,我将非常感激。
这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include "files.h"
struct MatrixObject *matrix;
struct MatrixObject{
size_t rows;
size_t columns;
int *numbers;
struct MatrixObject *pointToNext;
char sign;
};
struct MatrixObject *newMatrixObject (size_t n, size_t m) {
struct MatrixObject *retVal = malloc (sizeof (struct MatrixObject));
if (retVal == NULL)
return NULL;
retVal->numbers = malloc (n * m * sizeof (int*));
if (retVal->numbers == NULL) {
free (retVal);
return NULL;
}
retVal->pointToNext = malloc(sizeof(struct MatrixObject*));
if (retVal->pointToNext == NULL) {
free (retVal);
return NULL;
}
retVal->rows = n;
retVal->columns = m;
return retVal;
}
struct MatrixObject* getMatrixArray(){
struct MatrixObject *object;
int m, n;
if(scanf("%d %d", &n, &m) != 2){
errorHandle();
}
if(n<0 || m<0){
errorHandle();
}
object = newMatrixObject(n, m);
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
if(fscanf(stdin, "%d", &(object->numbers[(i*m)+j]))!=1){
errorHandle();
}
}
}
char temp;
int res;
while((res=fscanf(stdin, "%c", &temp))!=EOF){
if(res!=1){
errorHandle();
}
if(temp == '*' || temp == '+' || temp == '-'){
object->sign = temp;
object->pointToNext = getMatrixArray();
return object;
}
}
object->sign = 0;
object->pointToNext = 0;
return object;
}
void multiplyMatrix(struct MatrixObject *matrix1, struct MatrixObject *matrix2){
int newColumns = matrix2->columns;
int newRows = matrix1->rows;
int* newNumbers = malloc(newColumns * newRows * sizeof(*newNumbers));
int counter = 0;
if(matrix1->columns != matrix2->rows){
errorHandle();
}
for(int i = 0;i<newRows;i++){
for(int k = 0;k<newColumns;k++){
int sum = 0;
for(int j = 0;j<matrix1->columns;j++){
sum+= ((matrix1->numbers)[(i*matrix1->columns)+j]) * ((matrix2->numbers)[(j*matrix2->columns)+k]);
}
newNumbers[counter] = sum;
counter++;
}
}
struct MatrixObject mat = *matrix2;
free(matrix2->numbers);
free(matrix2);
matrix1->pointToNext = mat.pointToNext;
matrix1->sign = mat.sign;
free(matrix1->numbers);
matrix1->numbers = newNumbers;
matrix1->columns = newColumns;
matrix1->rows = newRows;
}
void addMatrix(struct MatrixObject *matrix1, struct MatrixObject *matrix2, char sign){
if(matrix1->columns != matrix2->columns || matrix1->rows != matrix2->rows){
errorHandle();
}
int columns = matrix1->columns;
int rows = matrix2->rows;
int* newNumbers = malloc(rows*columns*sizeof(*newNumbers));
for(int i = 0;i<rows;i++){
for(int j = 0;j<columns;j++){
if(sign == '+'){
newNumbers[i*columns + j] = matrix1->numbers[i*columns + j] + matrix2->numbers[i*columns + j];
}else{
newNumbers[i*columns + j] = matrix1->numbers[i*columns + j] - matrix2->numbers[i*columns + j];
}
}
}
struct MatrixObject mat = *matrix2;
free(matrix2->numbers);
free(matrix2);
matrix1->pointToNext = mat.pointToNext;
matrix1->sign = mat.sign;
free(matrix1->numbers);
matrix1->numbers = newNumbers;
}
int main(int argc, char *argv[])
{
struct MatrixObject *actualMatrix;
matrix = getMatrixArray();
actualMatrix = matrix;
while(actualMatrix->pointToNext != 0){
if(actualMatrix->sign == '*'){
multiplyMatrix(actualMatrix, actualMatrix->pointToNext);
}
else{
actualMatrix = actualMatrix->pointToNext;
}
}
printMatrix(matrix);
actualMatrix = matrix;
while(actualMatrix->pointToNext != 0){
if(actualMatrix->sign == '+' || actualMatrix->sign == '-'){
addMatrix(actualMatrix, actualMatrix->pointToNext, actualMatrix->sign);
}
}
printMatrix(matrix);
return 0;
}
这是我的 valgrind 的输出:
==30650==
==30650== HEAP SUMMARY:
==30650== in use at exit: 88 bytes in 6 blocks
==30650== total heap usage: 17 allocs, 11 frees, 2,416 bytes allocated
==30650==
==30650== Searching for pointers to 6 not-freed blocks
==30650== Checked 65,936 bytes
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 1 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 2 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 3 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 4 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== LEAK SUMMARY:
==30650== definitely lost: 32 bytes in 4 blocks
==30650== indirectly lost: 0 bytes in 0 blocks
==30650== possibly lost: 0 bytes in 0 blocks
==30650== still reachable: 56 bytes in 2 blocks
==30650== suppressed: 0 bytes in 0 blocks
==30650== Reachable blocks (those to which a pointer was found) are not shown.
==30650== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==30650==
==30650== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
这里是数轴的一些信息:
32: retVal->pointToNext = malloc(sizeof(struct MatrixObject*));
54: object = newMatrixObject(n, m);
71: object->pointToNext = getMatrixArray();
177:matrix = getMatrixArray();
最佳答案
我首先看到的是
struct MtrixObject *newMatrixObject (size_t n, size_t m) {
//...
retVal->pointToNext = malloc(sizeof(struct MatrixObject*));
if (retVal->pointToNext == NULL) {
free (retVal);
return NULL;
}
retVal 的编号在错误检查 block 中从未空闲过。请记住,释放一个结构体并不会释放由 malloc 初始化的任何内部变量
在您的 main 中,matrix 或 actualMatrix 不是免费的。看起来您正在创建默认矩阵 actualMatrix 并对其进行编辑,然后设置指针 pointToNext 以指向已编辑的矩阵。之后,您将 actualMatrix 设置回默认矩阵。 (这是我在这里看到的 LinkedList 吗?)
这意味着你有一个矩阵链,最后不是免费的。你应该试试
struct MatrixObject *temp;
while (matrix != NULL) {
temp = matrix.pointToNext;
free(matrix);
matrix = temp;
}
这将遍历第一个矩阵之后的所有矩阵并释放它们。
请注意,我不知道 printMatrix 做了什么,因为它从未出现在您的代码中。可能是您释放了其中的矩阵。
最后一个评论,因为你在方法中调用 errorHandle(),如果有一些错误,你很有可能没有释放一些 mallocs
void multiplyMatrix(struct MatrixObject *matrix1, struct MatrixObject *matrix2){
int newColumns = matrix2->columns;
int newRows = matrix1->rows;
int* newNumbers = malloc(newColumns * newRows * sizeof(*newNumbers));
int counter = 0;
if(matrix1->columns != matrix2->rows){
errorHandle();
}
//...
在这里,调用了 errorHandle,但几乎没有办法让你释放 newNumbers,因为它从未作为引用传入。这意味着它会四处漂浮,永远不会干净。
我建议在 errorHandle 之后分配 newNumbers
关于c - Valgrind block 丢失,从哪里释放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40633352/
我希望 valgrind 在发现第一个错误时停止并退出。 请勿推荐 --vgdb-error=1 :它不会退出 valgrind。您必须连接 gdb 并从那里终止。 --db-attach : 在最近
有人可以快速解释 Valgrind 的工作原理吗?一个例子:它如何知道内存何时被分配和释放? 最佳答案 Valgrind 基本上在“沙箱”中运行您的应用程序。在此沙箱中运行时,它能够插入自己的指令来进
我有一个因 SIGSEGV 而崩溃的应用程序。 --20183-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) -
我有一个因 SIGSEGV 而崩溃的应用程序。 --20183-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) -
我想使用 valgrind 检查长时间运行的进程是否存在内存泄漏。我怀疑我所追求的内存泄漏可能仅在执行几个小时后才会发生。我可以在 valgrind 下运行应用程序并获取 valgrind 日志,但这
我想用 valgrind 检查一个长时间运行的进程是否有内存泄漏。我怀疑我所追求的内存泄漏可能仅在执行数小时后才会发生。我可以在 valgrind 下运行应用程序并获得 valgrind 日志,但这样
如何在不通过 valgrind 命令选项启动它的情况下对每个 Process 实例执行 valgrind memcheck。 有没有办法将监控选项保存在进程中,而不是每次都使用 valgrind 命令
我使用了“--trace-children=yes”选项,我还使用了“--trace-children-skip=patt1,patt2,...”选项(过滤掉噪音过程)。但它对我来说仍然很慢,我的多进
我从 Valgrind 得到以下日志: MPK ==5263== 4 bytes in 1 blocks are still reachable in loss record 1 of 84 ==52
如何在 Valgrind 抑制文件中添加注释? 我需要为一个大型项目维护一个 Valgrind 抑制文件。我们从我们链接到的工具中过滤无法修复的错误。随着工具的新版本发布,此文件可能需要随着时间的推移
我有一个大程序要运行。使用 valgrind 需要几个小时才能运行。我听说有一些东西可以让我们为程序中的特定函数调用 valgrind。其余程序将正常执行(没有 valgrind env)。 任何人都
我可以用 valgrind 检测整数溢出缺陷吗?里面的哪个工具可以做到这一点? 最佳答案 Valgrind 没有可以检测整数溢出的工具。 您可能会使用 gcc 选项捕获这些错误: -ftrapv Th
我有一个简单的程序: int main(void) { const char sname[]="xxx"; sem_t *pSemaphor; if ((pSemaphor = sem_o
如何让 Valgrind 准确显示错误发生的位置?我编译了我的程序(通过 PuTTy 在 Windows 机器上通过 Linux 终端)添加了 -g 调试选项。 当我运行 Valgrind 时,我得到
或者最好是全部,而不仅仅是我的代码?我的程序使用 Gtk、Loudmouth 和其他一些东西,而这两个(以及它们背后的一些,libgcrypto、libssl)本身导致了如此多的错误,以至于我无法检测
我想尝试使用 valgrind 进行一些堆损坏检测。通过以下腐败“单元测试”: #include #include #include int main() { char * c = (ch
我看过类似的问题here ,但我的问题是我没有编辑 default.supp 文件的权限。例如,Valgrind 中是否有任何忽略所有抑制文件的命令行选项? 最佳答案 在 Valgrind 3.10.
我在一个运行无限循环的程序上使用 valgrind。 由于memcheck在程序结束后显示内存泄漏,但由于我的程序有无限循环,它永远不会结束。 那么有什么方法可以强制从 valgrind 时不时地转储
我一直在尝试使用 valgrind 查找一些可疑的内存错误。 在被分析的程序甚至到达我希望分析的点之前,它会因为对 mmap 的调用开始失败而退出。当它不在 valgrind 下时,这些调用会成功。
由于 OpenSSL 使用未初始化的内存,因此对使用 openldap2 的 libldap 的程序进行 Valgrind 是一件苦差事。存在一个 --ignore-fn选项,但仅适用于 Valgri
我是一名优秀的程序员,十分优秀!