Valgrind:地址0x0没有堆叠,malloc'd或(最近)免费获取更大的输入值

时间:2018-05-02 09:11:37

标签: c memory malloc valgrind

我正在尝试使用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()

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

1 个答案:

答案 0 :(得分:5)

查看一些malloc() manual:由于某种原因,它的参数类型为size_tint不保证保留任何可能的对象大小,size_t是。它是无符号顺便说一句 - 负面大小没有多大意义。

所以写一下

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

由于您的vint,您必须通过强制转换其中一个参数来强制将此乘法作为size_t完成。

更好的方法是将v设为unsigned long并使用strtoul()代替atoi()

然后,检查 malloc()的结果,然后再使用它。即使使用正确的大小参数,它仍可能返回NULL。如果是这样,这只是意味着你没有足够的RAM

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