[英]SegFault while using Malloc/Realloc on an uninitialized pointer
我正在开发一个“轻型无人机模拟器”(在 C 中),我的任务之一是在我左键单击 map 时添加一个 static 目标。到目前为止一切顺利。 问题是,我不想创建一个具有给定大小的矩阵作为全局变量,而是想从一个未初始化的指针指针开始,一旦我左键单击,我就会重新分配新的 memory,以便始终有足够的 memory 可用但不会更多. 另外,我的“矩阵”应该有 4 列用于 3D 坐标,1 列用于“激活”。
这是我的代码的一部分:
/* Main program */
double **TargetsArray;
int main(int argc, char *argv[]) {
/* Call of model-specific mouse handling function */
HandleSpecialMouseEvent(button, state, x, y, &ActualFlockingParams,
&ActualVizParams, TargetPosition, TargetsArray, Modder);
}
void HandleSpecialMouseEvent(int button,
int state,
int x,
int y,
flocking_model_params_t * FlockingParams,
vizmode_params_t * VizParams,
double * CoordTarg, double ** TargetsArray,
const int Modifier) {
static int cnt = 0;
if (button == GLUT_LEFT && state == GLUT_DOWN && Modifier == GLUT_ACTIVE_ALT) {
FillVect(CoordTarg, MouseCoordToReal_2D(x, VizParams->MapSizeXY,
VizParams->Resolution) + VizParams->CenterX, -MouseCoordToReal_2D(y, VizParams->MapSizeXY,
VizParams->Resolution) + VizParams->CenterY, 0);
printf("%d\n", cnt);
if (cnt == 0) {
TargetsArray = malloc( sizeof *TargetsArray );
TargetsArray[cnt] = malloc( sizeof **TargetsArray * 4);
printf("Hello");
TargetsArray[cnt][0] = CoordTarg[0];
TargetsArray[cnt][1] = CoordTarg[1];
TargetsArray[cnt][2] = 0;
TargetsArray[cnt][3] = 1;
cnt += 1;
}
else {
printf("Youhou");
TargetsArray = realloc(TargetsArray, sizeof *TargetsArray * (cnt + 1) );
TargetsArray[cnt] = malloc( sizeof **TargetsArray * 4);
TargetsArray[cnt][0] = CoordTarg[0];
TargetsArray[cnt][1] = CoordTarg[1];
TargetsArray[cnt][2] = 0;
TargetsArray[cnt][3] = 1;
TargetsArray[cnt - 1][3] = 0;
cnt += 1;
}
// for (int j = 0; j < cnt; j++) {
// for (int i = 0; i < 4; i++) {
// printf("%f\t", TargetsArray[j][i]);
// }
// printf("\n");
// }
}
}
我通常会遇到两种类型的错误:
0
Hello1
Youhou2
Erreur de segmentation (core dumped)
OR
0
Hello1
free(): invalid next size (fast)
Abandon (core dumped)
我知道有更简单的方法可以做到这一点,但我真的很想了解为什么这不起作用。 我很确定这是由于我使用malloc和realloc的方式,但我也不明白为什么在第一个“循环”中程序没有将 go 放入 if 语句中,而它打印“0”然后为什么它在打印计数器(cnt)之前打印“Hello”?
我希望我为您提供了足够的代码来理解我的问题,但如果缺少某些内容,请告诉我。
谢谢 !!
关于malloc和realloc, please check the lines about malloc, please check the memory is available and could be allocated, 都返回NULL
以防错误。
只需检查是否有足够的 memory,并且可以分配给两个 alloc 调用,如下所示:
TargetsArray = malloc( sizeof *TargetsArray );
if(TargetsArray == NULL){
//oh! not enough mem, or whatever...
}
//...
void* TargetsArray_ra = realloc(TargetsArray, sizeof(*TargetsArray) * (cnt + 1) );
if(TargetsArray_ra == NULL){
//oh! could not realloc
//if you wish to return, don't forget to free up the TargetsArray
if(TargetsArray != NULL){free(TargetsArray);TargetsArray=NULL;}
//return;
}else{//when realloc was success
TargetsArray = TargetsArray_ra ;
}
同样检查TargetsArray[cnt] = malloc( sizeof **TargetsArray * 4);
, 在访问它之前确保它需要一个正确的非NULL
ptr
那些 if-else 块也有点相同,除了最后一个语句,除此之外当你调试代码时,你在哪一行得到段错误? 您确定传递的CoordTarg
不是NULL
并且长度合适? FillVect
函数呢? 它按预期工作吗?
您需要更改函数的参数TargetsArray
,以便它指向全局变量,而不仅仅是存储相同的值。
主要程序:
double **TargetsArray;
int main(int argc, char *argv[]) {
/* Call of model-specific mouse handling function */
HandleSpecialMouseEvent(button, state, x, y, &ActualFlockingParams,
&ActualVizParams, TargetPosition, &TargetsArray, Modder);
}
void HandleSpecialMouseEvent(int button,
int state,
int x,
int y,
flocking_model_params_t * FlockingParams,
vizmode_params_t * VizParams,
double * CoordTarg, double *** TargetsArray,
const int Modifier) {
static int cnt = 0;
if (button == GLUT_LEFT && state == GLUT_DOWN && Modifier == GLUT_ACTIVE_ALT) {
FillVect(CoordTarg, MouseCoordToReal_2D(x, VizParams->MapSizeXY,
VizParams->Resolution) + VizParams->CenterX, -MouseCoordToReal_2D(y, VizParams->MapSizeXY,
VizParams->Resolution) + VizParams->CenterY, 0);
printf("%d\n", cnt);
if (cnt == 0) {
*TargetsArray = malloc( sizeof **TargetsArray );
(*TargetsArray)[cnt] = malloc( sizeof ***TargetsArray * 4);
printf("Hello\n");
(*TargetsArray)[cnt][0] = CoordTarg[0];
(*TargetsArray)[cnt][1] = CoordTarg[1];
(*TargetsArray)[cnt][2] = 0;
(*TargetsArray)[cnt][3] = 1;
cnt += 1;
}
else {
printf("Youhou");
*TargetsArray = realloc(*TargetsArray, sizeof **TargetsArray * (cnt + 1) );
(*TargetsArray)[cnt] = malloc( sizeof ***TargetsArray * 4);
(*TargetsArray)[cnt][0] = CoordTarg[0];
(*TargetsArray)[cnt][1] = CoordTarg[1];
(*TargetsArray)[cnt][2] = 0;
(*TargetsArray)[cnt][3] = 1;
(*TargetsArray)[cnt - 1][3] = 0;
cnt += 1;
}
// for (int j = 0; j < cnt; j++) {
// for (int i = 0; i < 4; i++) {
// printf("%f\t", *TargetsArray[j][i]);
// }
// printf("\n");
// }
}
}
注意:括号非常重要
每次重新分配 memory 时,都会在 TargetsArray 中存储一个新的TargetsArray
地址。 由于您正在更改 function 中的值,因此您需要为 function 提供变量TargetsArray
的地址。 其他方式,您将仅将重新分配的地址存储在函数的本地TargetsArray
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.