在 C 中访问动态数组的一部分?
Accessing portions of a dynamic array in C?
我知道,另一个动态数组问题,这个问题有点不同,所以也许值得回答。我正在用 C 语言和 SDL 制作一个地形生成器,我在屏幕周围绘制了 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 使其变为正值,然后将其乘以 2 以在镜头前获得一个块相机
好吧,显然只初始化了一个,这里是渲染代码
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);
那么我做错了什么?我的意思是我现在真的很困惑......在 Vectors 被推荐代替动态数组之前,我真的不喜欢使用它们,我想学习处理这样的事情,而不仅仅是实现一些简单的修复。
很多混淆(这在 C 指针中很常见)。
以下代码未提供预期的答案:arrayLen = sizeof(totalTiles * sizeof(Tile));
totalTiles * sizeof(Tile)
甚至都不是一种类型,我很惊讶它能编译。 编辑:请参阅下面的 molbnilo 评论。 因此它提供了 return 类型的大小。
无论如何,正确的答案应该是:
arrayLen = totalTiles;
因为这是你在下一个循环中需要的:
//Clear all elements to zero.
for (int i = 0; i < arrayLen; i++)
{
Tile tile = {};
TileMap[i] = tile;
}
您不需要 table 的大小,您需要它的元素数量。
您的示例中还有其他混淆,它们不会直接影响代码的其余部分,但最好更正它们:
Tile* TileMap = (Tile*)malloc(0 * sizeof(Tile*));
:避免分配大小为 0.
int arrayLen = sizeof(TileMap);
:不,它不是 arrayLen
,只是指针的大小(因此在 32 位二进制文件上是 4 个字节)。请记住 TileMap
未定义为 table,而是定义为分配有 malloc()
的指针,然后是 realloc()
.
我知道,另一个动态数组问题,这个问题有点不同,所以也许值得回答。我正在用 C 语言和 SDL 制作一个地形生成器,我在屏幕周围绘制了 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 使其变为正值,然后将其乘以 2 以在镜头前获得一个块相机
好吧,显然只初始化了一个,这里是渲染代码
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);
那么我做错了什么?我的意思是我现在真的很困惑......在 Vectors 被推荐代替动态数组之前,我真的不喜欢使用它们,我想学习处理这样的事情,而不仅仅是实现一些简单的修复。
很多混淆(这在 C 指针中很常见)。
以下代码未提供预期的答案:arrayLen = sizeof(totalTiles * sizeof(Tile));
totalTiles * sizeof(Tile)
甚至都不是一种类型,我很惊讶它能编译。 编辑:请参阅下面的 molbnilo 评论。 因此它提供了 return 类型的大小。
无论如何,正确的答案应该是:
arrayLen = totalTiles;
因为这是你在下一个循环中需要的:
//Clear all elements to zero.
for (int i = 0; i < arrayLen; i++)
{
Tile tile = {};
TileMap[i] = tile;
}
您不需要 table 的大小,您需要它的元素数量。
您的示例中还有其他混淆,它们不会直接影响代码的其余部分,但最好更正它们:
Tile* TileMap = (Tile*)malloc(0 * sizeof(Tile*));
:避免分配大小为 0.
int arrayLen = sizeof(TileMap);
:不,它不是 arrayLen
,只是指针的大小(因此在 32 位二进制文件上是 4 个字节)。请记住 TileMap
未定义为 table,而是定义为分配有 malloc()
的指针,然后是 realloc()
.