班级:
class Tile {
public:
long long size, joint;
};
我的主要成员:
int main() {
//
double minW, minL;
unsigned tileCap = 10, tileCount = 0;
bool wasTransformed = false;
auto *tiles = (Tile*)calloc(tileCap, sizeof(Tile) );
GetInput(&minW, &minL, &tiles, &tileCount, &wasTransformed);
//etc.
}
这里有问题的功能是GetInput()
:
void GetInput(double *w, double *l, Tile **tiles, unsigned *tileCount, bool *needTransform) {
//
printf("Min dimensions:\n");
if (scanf("%lf %lf", w, l) != 2)
BadInput();
if (!CorrectSize(*w) || *w == 0)
BadInput();
if (!CorrectSize(*l) || *w == 0)
BadInput();
unsigned tileCap = 10;
*tiles = (Tile*)calloc(tileCap, sizeof(Tile) );
printf("Tiles:\n");
double tileSize, tileJoint;
int argc;
do {
argc = scanf("%lf %lf", &tileSize, &tileJoint);
if(argc == EOF) {
break;
}
if (tileSize == 0 || !CorrectSize(tileSize) || !CorrectSize(tileJoint) || argc != 2)
BadInput();
if(! *needTransform) {
*needTransform = HasFloatingPoint(tileSize) || HasFloatingPoint(tileJoint);
if(*needTransform)
TransformPrevious(*tiles, *tileCount);
}
if(*needTransform) {
//transform this
tileSize *= 10;
tileJoint *= 10;
}
(*tiles)[*tileCount].size = (long long)tileSize + (long long)tileJoint;
(*tiles)[*tileCount].joint = (long long)tileJoint;
*tileCount += 1;
if( (*tileCount) == tileCap) {
DoubleArray(tiles, &tileCap);
}
} while(true);
}
我的DoubleArray()
:
void DoubleArray(Tile **array, unsigned *cap) {
//
auto *tmp = (Tile*)realloc(*array, 2 * sizeof(Tile) );
if(tmp) {
*array = tmp;
*cap *= 2;
(*cap)--;
} else {
printf("Error allocating memory.\n");
}
}
运行程序似乎很好,没有显示错误,结果似乎是正确的。例如:
360 217
0.1 0.0
0.2 0.0
0.3 0.0
0.4 0.0
0.6 0.0
0.8 0.0
1.2 0.0
2.4 0.0
4.1 0.0
8.2 0.0
12.3 0.0
16.4 0.0
24.6 0.0
32.8 0.0
49.2 0.0
Valgrind在12.3 0
打印Invalid write of size 8
。所以在我看来,我错误地重新分配了内存。但是,如果我是,如果我打印出来,为什么值正常加载?换句话说,所有输入都正确加载到数组中。
那么我做错了什么?使用memset
?是不是free
正确?
答案 0 :(得分:2)
您正在错误地重新分配内存。 std::malloc
,std::calloc
和std::realloc
的接口在某种程度上不一致,并且与要分配的大小有些混淆。 std::malloc
和std::realloc
采用单个大小的参数,该参数应为对象数量乘以其大小。 std::calloc
有两个参数,一个用于对象数,另一个用于一个对象的大小。
您正在致电
auto *tmp = (Tile*)realloc(*array, 2 * sizeof(Tile) );
这(重新)为两个Tiles分配空间。你应该写点像
*cap *= 2;
auto *tmp = (Tile*)realloc(*array, *cap * sizeof(Tile) );
额外的内存将是未初始化的,因此您可能需要将memset()设置为0。
答案 1 :(得分:-1)
void DoubleArray(Tile **array, unsigned *cap) {
//
auto *tmp = (Tile*)realloc(*array, *cap);
if(tmp) {
*array = tmp;
*cap *= 2;
(*cap)--;
} else {
printf("Error allocating memory.\n");
free(tmp);
}
}
tmp
尚未重新分配(由于错误),为什么free()
呢?