重写C++;C类 < >我在C++中编写的C++类有一些麻烦。 C++类具有一些私有属性: int grid_width; int grid_height; const int group_width = 2; const int group_height = 4; std::vector<int> buffer;

重写C++;C类 < >我在C++中编写的C++类有一些麻烦。 C++类具有一些私有属性: int grid_width; int grid_height; const int group_width = 2; const int group_height = 4; std::vector<int> buffer;,c++,c,arrays,memory-management,struct,C++,C,Arrays,Memory Management,Struct,它还具有如下清晰的功能: void grid::clear() { // get_buffer_size returns elements in the buffer vector for (int i = 0; i < get_buffer_size(); ++i) { buffer[i] = 0x00; } } 但是由于某种原因,我的C代码中的元素数量总是2? 有人知道我把事情搞砸了吗 如果网格初始化为4和8,则预期的缓冲区大小应为4,而不是2

它还具有如下清晰的功能:

void grid::clear() {
    // get_buffer_size returns elements in the buffer vector
    for (int i = 0; i < get_buffer_size(); ++i) {
        buffer[i] = 0x00;
    }
}
但是由于某种原因,我的C代码中的元素数量总是2? 有人知道我把事情搞砸了吗


如果网格初始化为4和8,则预期的缓冲区大小应为4,而不是2。如果将其初始化为10和24,则预期大小为30,但在我的C示例中仍然为2。

'sizeof'返回指定类型使用的字节数。在这种情况下,sizeof(g->buffer)等于sizeof(int*),因为您使用的是x64处理器,所以所有指针的sizeof都是8。

您的
grid\u new
正在分配一个
grid
结构数组,而不是一个元素数正确的
grid

您需要设置
缓冲区

此外,网格中元素的数量基于宽度/高度,而不是
sizeof(g->buffer)
,后者是指针的大小,而不是指针指向的区域

以下是重构后的代码:

const int group_height = 4;
const int group_width = 2;

typedef struct {
    int width;
    int height;
    int *buffer;
} grid;

grid *
grid_new(int grid_width, int grid_height)
{
    if ((grid_width % 2 != 0) || (grid_height % 4 != 0))
        return NULL;

    grid *p_grid = calloc(1,sizeof(*p_grid));

    // FIXME -- why???
    grid_width /= group_width;
    grid_height /= group_height;

    p_grid->width = grid_width;
    p_grid->height = grid_height;

    p_grid->buffer = calloc(grid_width * grid_height,sizeof(int));

    return p_grid;
}

void
grid_free(grid *p_grid)
{
    free(p_grid->buffer);
    free(p_grid);
}

void
grid_clear(grid *g)
{
    // ToDo: Iterate over all elements in the buffer
    int elements = g->width * g->height;

    printf("Elements: %i", elements);
}

sizeof(g->buffer)
——这并不是你所认为的那样。这不会给您分配的字节数。无论您使用的是
C++
还是
C
,情况都是如此。如果您需要知道指向的数组有多少个元素,则需要将该值存储在某个位置
std::vector
在内部执行此操作,在C语言中,您必须自己执行此操作(除非您使用具有良好动态数组实现的库),一旦您解决@PaulMcKenzie提到的问题,您将遇到其他问题。请注意,您只有一个
calloc
,但有两个
free
s。您也从不初始化
p\u grid->buffer
。我假设您打算使用<代码> CALLC来分配<代码>缓冲区< /> >的空间,但这不是您使用它的方式。信不信由你, C>代码>允许你按值返回<代码>结构>代码>,就像C++一样。对于
grid\u new
函数,无需返回
grid*
。声明本地
网格
,正确初始化并返回它<代码>栅格新(栅格宽度、栅格高度)。这样做也可能防止@MilesBudnek指出的错误。我明白了。这是有道理的。必须习惯于从C++到C的切换,其中有一些令人惊讶的惊喜;这也是C的推荐风格指南,返回类型在函数签名上方的单独一行中?大多数风格指南都推荐它。但是《linux内核风格指南》说它应该在同一条线上。我这样做有几个原因:(1)更清晰/更清晰[IMO,基于40年的经验](2)您可以使用
regex
(例如):
vi`grep-rl^grid\u new[(]。`
(3)它有助于保持行数<80个字符[推荐]
typedef struct
{
    int width;
    int height;
    int *buffer;
} grid;

grid *grid_new(int grid_width, int grid_height)
{
    if ((grid_width % 2 != 0) || (grid_height % 4 != 0))
        return NULL;

    int group_height = 4;
    int group_width = 2;

    grid *p_grid = calloc(grid_width / group_width * grid_height / group_height, sizeof(int));
    p_grid->width = grid_width;
    p_grid->height = grid_height;

    return p_grid;
}

void grid_free(grid *p_grid)
{
    free(p_grid->buffer);
    free(p_grid);
}

void grid_clear(grid *g)
{
    // ToDo: Iterate over all elements in the buffer
    int elements = sizeof(g->buffer) / sizeof(int);
    printf("Elements: %i", elements);
}
const int group_height = 4;
const int group_width = 2;

typedef struct {
    int width;
    int height;
    int *buffer;
} grid;

grid *
grid_new(int grid_width, int grid_height)
{
    if ((grid_width % 2 != 0) || (grid_height % 4 != 0))
        return NULL;

    grid *p_grid = calloc(1,sizeof(*p_grid));

    // FIXME -- why???
    grid_width /= group_width;
    grid_height /= group_height;

    p_grid->width = grid_width;
    p_grid->height = grid_height;

    p_grid->buffer = calloc(grid_width * grid_height,sizeof(int));

    return p_grid;
}

void
grid_free(grid *p_grid)
{
    free(p_grid->buffer);
    free(p_grid);
}

void
grid_clear(grid *g)
{
    // ToDo: Iterate over all elements in the buffer
    int elements = g->width * g->height;

    printf("Elements: %i", elements);
}