Valgrind:仅对于较大的输入值,地址 0x0 不会被堆栈、分配或(最近)释放

问题描述 投票:0回答:2

我正在尝试实现 Dijikstra,这是我拥有的图形生成代码

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>
#define MAX 300
int main (int argc, char *argv[]){
    int v = atoi(argv[1]);
    int SIZE = v*v;
    int* adjMatrix = malloc(sizeof(int)* SIZE);
    graphGeneration(adjMatrix, v);
    free(adjMatrix);
    return 0;
}

void graphGeneration(int* adj, int numV){
    int i, j, r;
    for(i = 0; i< numV; i++){
        for(j=0; j < numV; j++){
            if(i == j){
                adj[i * numV + j] = 0;
            }
            else{
                r = rand() % MAX;
                adj[i * numV + j] = r;
                adj[j * numV + i] = r;
            }
        }
    }

}

当我尝试输入 1000 的 v 值时,它似乎工作正常,但是当我尝试输入 v = 10,000+ 的值时,我遇到了段错误(特别是我注意到的数字是 50,000)。运行 valgrind 会导致我在该方法的标题中出现错误。 为了方便起见,重新发布在这里:

Invalid write of size 4
at 0x400800: graphGeneration 
by 0x4006E3: main
Address 0x0 is not stack'd, malloc'd or (recently) free'd
Access not within mapped region at address 0x0

有人对如何调试这个有任何想法或者这里是否有任何明显的错误?

我也在 valgrind 中注意到了这一点

Warning: silly arg (-7179869184) to malloc()

我不确定这是否相关,但这似乎也是一件奇怪的事情。

c memory malloc valgrind
2个回答
7
投票

看看一些

malloc()
手册:它的参数是
size_t
类型是有原因的。
int
不能保证容纳任何可能的对象大小,
size_t
可以。顺便说一句,它是无符号的——负大小没有多大意义。

所以就写吧

size_t SIZE = ((size_t)v) * v;

因为你的

v
是一个
int
你必须通过强制转换参数之一来强制这个乘法作为
size_t
完成。

稍微好一点的方法是将

v
制作为
unsigned long
并使用
strtoul()
代替
atoi()


然后,在使用之前检查您的

malloc()
的结果。即使使用正确的大小参数,它仍然可能返回
NULL
。如果是这样,这仅仅意味着您当时没有足够的可用内存

毕竟,使用

v=10000
并假设
int
占用四个字节(这很常见),您已经尝试一次分配 400 MB。


0
投票

他是中本聪..但是这是构建项目的投资组合

不要试图理解这一点..这会让你很快发疯..

© www.soinside.com 2019 - 2024. All rights reserved.