我知道,另一个动态阵列问题,这个问题虽然有点不同,但也许值得回答。我正在使用SDL在C中制作地形生成器,我在屏幕周围绘制了9个块,与屏幕大小成比例,这样可以在将来更容易地生成地形。
这意味着我必须能够在任何给定点调整数组大小,所以我创建了一个动态数组(至少根据我在堆栈上找到的答案)和所有SEEMS工作正常,没有什么是崩溃,它甚至可以绘制一个瓷砖....但只有一个。我正在看它,是的,它确实在迭代数组但只写入一部分内存。我正在使用一个名为Tile的结构,它只包含一个矩形的x,y,w和h。
这是我用来分配数组的代码
Tile* TileMap = (Tile*)malloc(0 * sizeof(Tile*));
int arrayLen = sizeof(TileMap);
TileMap = (Tile*)realloc(TileMap, (totalTiles) * sizeof(Tile));
arrayLen = sizeof(totalTiles * sizeof(Tile));
totalTiles只是我之前在屏幕上计算过的图块数量,我检查了数学并且它是正确的,它甚至分配了适当的内存量。这是我用来初始化数组的代码:
//Clear all elements to zero.
for (int i = 0; i < arrayLen; i++)
{
Tile tile = {};
TileMap[i] = tile;
}
所以对我来说奇怪的是它正在考虑一个磁贴的大小(16个字节)* totalTiles(78,000)等于4 ....当我深入到数组时,它只有一个其中的单个矩形也被清除,所以当我计算每个瓷砖的尺寸时:
//Figure out Y and heights
for (int i = startY; i <= (startY*(-1)) * 2; i += TILE_HEIGHT)
{
TileMap[i].y = i * TILE_HEIGHT;
TileMap[i].h = TILE_HEIGHT;
//Figure out X and widths
for (int j = startX; j <= (startX*(-1)) * 2; j += TILE_WIDTH)
{
TileMap[i].x = i * TILE_WIDTH;
TileMap[i].w = TILE_WIDTH;
}
}
*旁注,startX是我用于在相机后面绘制块的负偏移量,所以我用-1乘以它使其为正,然后将它计时两次以获得相机前面的一个块< / p>
好吧,显然只会初始化一个,这里是渲染代码
for (int i = 0; i < totalTiles; i++)
{
SDL_Rect currentTile;
currentTile.x = TileMap[i].x;
currentTile.y = TileMap[i].y;
currentTile.w = TileMap[i].w;
currentTile.h = TileMap[i].h;
SDL_RenderDrawRect(renderer, ¤tTile);
}
free(TileMap);
那我在这里做错了什么?我的意思是我现在只是感到困惑......在推荐使用Vector代替动态数组之前,我并不喜欢使用它们,我想学习处理这样的东西,而不仅仅是实现一些简单的固定。
答案 0 :(得分:1)
很多混乱(这在C指针中很常见)。
以下代码未提供预期答案:arrayLen = sizeof(totalTiles * sizeof(Tile));
totalTiles * sizeof(Tile)
甚至不属于某种类型,我对它的编译感到惊讶。 编辑:请参阅下面的molbnilo评论。因此它提供了返回类型的大小。
无论如何,正确答案应该是:
arrayLen = totalTiles;
因为这是您在下一个循环中所需要的:
//Clear all elements to zero.
for (int i = 0; i < arrayLen; i++)
{
Tile tile = {};
TileMap[i] = tile;
}
你不需要桌子的大小,你需要它的元素数量。
您的示例中还有其他混淆,它们不会直接影响其余代码,但更好地纠正它们:
Tile* TileMap = (Tile*)malloc(0 * sizeof(Tile*));
:避免分配大小为0.
int arrayLen = sizeof(TileMap);
:不,它不是arrayLen
,只是指针的大小(因此在32位二进制文件上是4个字节)。请记住,TileMap
未定义为表格,而是定义为malloc()
然后realloc()
分配的指针。