【发布时间】:2021-05-17 22:40:21
【问题描述】:
您好,我正在使用 C 来完成学校作业。我不得不道歉,我对像 C 这样的低级语言非常生疏。当我尝试动态初始化一些数组时,当 n>100 时,我的代码给了我 segfault 11。我试图启动 Valgrind 以了解发生了什么,但我不能完全理解调试日志,因为它报告的内存块远小于我打算以较大的 n 值分配的内存块。任何人都可以帮忙看看有什么问题吗?谢谢!
我的代码(当我将 2D 矩阵的每个条目设置为 1 时发生错误):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int n;
typedef struct{
float x;
float y;
} Point2D;
float rand_float(){
return (float)rand()/RAND_MAX;
}
int main(void) {
srand(time(NULL));
scanf("%d", &n);
int (*adjm)[n][n] = malloc( sizeof(float[n][n])+1 );
Point2D (*vcoord)[n] = malloc( sizeof(Point2D[n])+1 );
// initialize coords
for (int i = 0; i < n; i++){
(*vcoord[i]).x = rand_float();
(*vcoord[i]).y = rand_float();
printf("%d %f %f \n", i, (*vcoord[i]).x, (*vcoord[i]).y);
}
for (int x = 0; x < n; x++){
for (int y = 0; y < n; y++){
*adjm[x][y] = 1;
}
}
// free up memory
free(*adjm);
free(*vcoord);
return 0;
}
当我让 n=200 时,Valgrind 日志的前几行:
==18832== Memcheck, a memory error detector
==18832== Copyright (C) 2002-2017, and GNU GPLd, by Julian Seward et al.
==18832== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==18832== Command: ./out
==18832== Parent PID: 1670
==18832==
==18832== Invalid write of size 4
==18832== at 0x1089F4: main (in /home/usrname/valgrindtest/out)
==18832== Address 0x5257050 is 1,600 bytes inside a block of size 1,601 alloc'd
==18832== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18832== by 0x1089B8: main (in /home/usrname/valgrindtest/out)
==18832==
==18832== Invalid write of size 4
==18832== at 0x108A23: main (in /home/usrname/valgrindtest/out)
==18832== Address 0x5257054 is 3 bytes after a block of size 1,601 alloc'd
==18832== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
【问题讨论】:
-
int (*adjm)[n][n] = malloc( sizeof(float[n][n])+1 );: 看起来你的意思是int而不是float? -
free(*adjm);等错误;malloc返回的指针在adjm中,而不是在*adjm中。应该是free(adjm); free(vcoord); -
非常感谢!我将 int 更改为 float 但段错误仍然出现在同一位置。还要感谢您指出 free(.) 的错误用法...我真的需要重新整理一下这些内容。
-
最重要的是,
malloc(sizeof(float[n][n])+1)并没有像您期望的那样分配矩阵。sizeof(float[n][n])等于sizeof(float*)可能是 8,因此总共是 9 个字节(总是)。 -
@CaptainTrojan:这不正确。
float[n][n]本身不是指针,衰减不会在这里发生。但是+1没有任何意义。
标签: c memory-management segmentation-fault