我无法弄清楚如何做malloc
。以下代码只输入前5行然后停止,任何帮助将不胜感激!
// Read query points from query file------------------------------
double **queryPoint;
token=(char*)malloc(40);
int qp_count=0;
i=0;
qp_count=0;
while(fgets(line,sizeof(line),queryFile)!=NULL)
{
queryPoint=(double*)malloc(sizeof(double**));
queryPoint[qp_count]=(double*)malloc(sizeof(double*)*2);
printf("line:%s",line);
token = strtok(line," ,\t");
queryPoint[qp_count][0]=atof(token);
token = strtok(NULL, " ,\t");
printf("l[%d]=%lf \n",qp_count,queryPoint[qp_count][0]);
queryPoint[qp_count][1]=atof(token);
token = strtok(NULL, " ,\t");
printf("l[%d]=%lf \n",qp_count,queryPoint[qp_count][1]);
qp_count++;
}
{ 这是查询文件的形式
9.85797 5.72533
9.58711 2.09899
2.28203 7.19344
4.49096 5.50094
6.05297 1.60751
6.19901 1.52312
} ... 总计30行
答案 0 :(得分:4)
queryPoint=(double*)malloc(sizeof(double**));
queryPoint[qp_count]=(double*)malloc(sizeof(double*)*2);
你显然已经对malloc
的强制转换,大小和其他各种属性感到困惑,所以让我们从正确的malloc语法开始。
首先,在C中没有必要转换malloc操作的结果,因为它总是返回一个指针 - 指针的类型指的是指向数据的类型,而不是指针本身,它总是寄存器的大小。但是,在C ++中,它被强制转换它。
现在,malloc的一般语法是:
TYPE* pointer = malloc(n * sizeof(TYPE));
其中TYPE
是某种类型。 sizeof
应始终是一个间接级别,小于您要分配的指针。 (所以TYPE**
给你一个TYPE*
的malloc。 n是要分配的此大小的块数,因此如果要分配100个双精度,那就是n
。
无论如何,你已经声明double** queryPoint;
所以你的第一个malloc应该是:
queryPoint = (double**) malloc(some_size*sizeof(double*));
这给了我们一个大小为some_size
的指针数组。就像任何其他阵列一样,您可以根据需要realloc
,尽管预先确定数量可能是理想的。然后,对于您希望分配的每一行,您只需从queryPoint
中选择一个偏移量并分配该特定指针所指向的双精度数组,如下所示:
queryPoint[i] = (double*) malloc(sizeof_this_array*sizeof(double));
然后,通过两个下标访问2D数组中的特定点:queryPoint [x] [y];
正如其他人所说的那样,realloc
是一个选项,但我建议你每次填充数组时都要加上一个固定的数量,或者只是加倍你的数量,因为内存是(相对)便宜的,这将是保存系统调用或六个。
现在,我已经讨论了指针等,所以我要绘制一个强制性的内存表,以便你可以看到它的样子:
|Address | Contents | Comments
|-------------|---------------|-------------------------
|0x12345 | 0x20000 | double** queryPointer
| ... | ... | ...
|0x20000 | 0x30000 | double* queryPointer[0]
|0x20001 | 0x30016 | double* queryPointer[1]
|0x20002 | 0x30032 | double* queryPointer[2]
| ... | ... | ...
|0x30000 | 0183737722122 | These together make up the floating
|0x30001 | 0183737722122 | point at double queryPointer[0][0]
|0x30002 | 0183737722122 |
| ... | ... | ...
|0x30016 | 0183737722122 | These together make up the floating
|0x30017 | 0183737722122 | point at double queryPointer[0][1]
|0x30018 | 0183737722122 |
| ... | ... | ...
指针只是一个包含地址的地址,因此0x12345
只是指向第一个malloc的一组地址的开头。这是一个指针数组,所以只是一个包含内存地址的内存地址集合,它指向实际值,如0x3***
范围所示。请注意,所有地址大小,数据大小和值表示都非常垃圾。
那正在发生。
此外,请不要忘记为您分配的每个内存地址free()
。
答案 1 :(得分:3)
在开头初始化:
double **queryPoint = 0;
int qp_count = 0;
每次拨打电话:
// call realloc to make the space for points larger by one element
queryPoint = realloc(queryPoint, sizeof(double*)*(qp_count+1));
// allocate space for the new point
queryPoint[qp_count] = malloc(sizeof(double)*2);
// increase the point count
qp_count++;
请注意,您可以使用realloc来调整行的空间大小。另请注意,您应该添加错误处理。
释放你需要打电话的记忆:
for(int i=0;i<qp_count;i++)
free(queryPoint[i]);
free(queryPoint);
答案 2 :(得分:0)
变量queryPoint
每次为一个指针分配空间,该指针在索引0(queryPoint[0]
)处可用。您尝试在queryPoint[qp_count]
添加内存。这个指数没有记忆。要修复,请使用尽可能多的指针分配queryPoint来读取文件。
int MAX_POINTER_COUNT = 10000 // whatever you choose
double** queryPoint=(double**)malloc(MAX_POINTER_COUNT * sizeof(double**));
一定不要写在数组末尾!这样做是一个潜在的漏洞溢出错误。 (特别是如果您阅读从外部提供的数据)。
答案 3 :(得分:0)
你走在正确的轨道上。 queryPoint
基本上是一个数组数组。但是,每次循环时,都会将之前的queryPoint
指针替换为新的指针double*
。你真正想做的是用一个指针增长queryPoint
:
queryPoint = (double**)realloc(queryPoint, sizeof(double*)*(qp_count+1));
(请注意,要使其工作queryPoint
,请将其初始化为NULL
。)
此外,您的第二次分配应该是sizeof(double)*2
,而不是sizeof(double*)*2
。
注意模式:在malloc
(或realloc
)内,我们有一个sizeof(TYPE)
。然后将返回值强制转换为TYPE*
。例如:
p = (double*)malloc(sizeof(double)*n);
pp = (double**)malloc(sizeof(double*)*n);
答案 4 :(得分:0)
泄漏token = malloc(40);
行分配的空间;那不好。
您没有显示line
的定义。
每次循环时,都会泄漏先前分配给queryPoint
的空间。
您在queryPoint=(double*)malloc(sizeof(double**));
上的投射是错误的;不应为double **queryPoint;
分配double *
。关于演员是否是一个好主意,意见分歧(不一定均匀)。
每次在第一个循环之后的循环中,您可以访问分配给queryPoint
的区域之外的空间。
您初始化int qp_count = 0;
,然后使用qp_count = 0;
再次将其设置为零,其中两个分配中的一个就足够了。
循环中的第二个strtok()
也可能正在寻找换行符。
您不会检查strtok()
是否找到了令牌。您不检查atof()
是否成功。 (实际上,无法检查atof()
;您可能需要使用strtod()
。)
答案 5 :(得分:0)
您应该首先更准确地定义您要执行的操作。
您不知道文件中有多少行,因此您最初不知道二维数组必须有多少行。最初的问题/问题是错误的。二维数组不适合这种类型的条件。
链表似乎更合适。如果每行(行)只有两个值,则结构可能更合适,以便您可以将指针添加到下一个queryPoint对。
答案 6 :(得分:0)
您希望在此次通话中分配多少字节?
queryPoint=(double*)malloc(sizeof(double**));
malloc()实际给你了多少?
它为您提供了void *
中的多个字节,在您的32位计算机上可能有8个。
这里发生了什么?
queryPoint[qp_count]=(double*)malloc(sizeof(double*)*2);
您正在向右存储到queryPoint中,覆盖malloc()在前一行中给出的指针。这是你想要的吗?
答案 7 :(得分:-2)
这就是你malloc
二维数组的方式:
double (*two_dim_array)[ncols] = malloc(nrows * sizeof *two_dim_array);