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

Bra*_*eme 2 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;
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

当我尝试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
Run Code Online (Sandbox Code Playgroud)

任何人有任何想法如何调试这个或如果有任何明显的错误?

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

Warning: silly arg (-7179869184) to malloc()
Run Code Online (Sandbox Code Playgroud)

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

小智 5

看看一些malloc()手册:它的论证是size_t有原因的.int不保证保持任何可能的对象大小,size_t是.它是无符号顺便说一句 - 负面尺寸没有多大意义.

所以写吧

size_t SIZE = ((size_t)v) * v;
Run Code Online (Sandbox Code Playgroud)

因为你v是一个int你必须通过强制size_t转换其中一个参数来强制执行这个乘法.

一个稍微好一点的办法是让v一个unsigned long和使用strtoul()代替atoi().


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

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