【问题标题】:Memset on pointer of pointers - why won't it work?指针指针上的 Memset - 为什么它不起作用?
【发布时间】:2021-10-28 01:19:38
【问题描述】:

我正在用 c 实现一个矩阵库。我已经创建了一个向量库,并且我已经将一个矩阵定义为一个指向向量的指针集合(因此每个指针都引用一个向量结构,它是矩阵列。)我有一个指针指针而不是一个数组指针的数量,因为 a) 我希望锯齿状矩阵成为可能 b) 我希望向量运算在矩阵的各个列上起作用 c) 我希望实际矩阵是动态的。

这里是矩阵类型定义:

    typedef struct mat {
    size_t alloc; // num of allocated bytes
    size_t w, h; // dimensions for the matrix
    vec** cols; // each column is a vector
    } mat;

假设我想调整矩阵的尺寸。以下代码对我来说很好用:

    void resizem(mat* m, size_t w, size_t h) {
    m -> alloc = w * VECTOR_SIZE;
    m -> cols = realloc(m -> cols, m -> alloc);
//    if(w > m -> w) {
//        memset(m -> cols + m -> w, init_vec(h), (w - (m -> w)) * VECTOR_SIZE);
//    }
    if(w > m -> w) {
        for(int i = m -> w; i < w; i++) {
            m -> cols[i] = init_vec(h);
        };
    }
    for(int i = 0; i < w; i++) {
        resizev(m -> cols[i], h);
    };
    m -> w = w;
    m -> h = h;
}

我的方法如下:1)重新计算要重新分配的字节量并将其存储在矩阵结构中(列数 * 列大小) 2)将内存重新分配给列 3)如果矩阵“增长”在宽度上,每个新列都需要初始化为默认向量。 4) 调整矩阵中每个向量的大小。

但是请注意注释掉的行。 为什么我不能在列指针上添加一个偏移量(前一个矩阵的大小),然后在其余列上使用 memset 将它们初始化为默认向量?当我运行它时它不起作用,所以我改用 for 循环。

请注意,如果它有帮助的话,这里是到目前为止向量库的 github 链接:Github link

【问题讨论】:

  • 请不要在-&gt; 周围放置空格。对于有经验的程序员来说,这不是惯用且难以阅读的。
  • “它不起作用”不是问题描述。编辑问题以提供minimal reproducible example,包括样本观察到的输出(或其他观察到的程序行为)和所需的输出。请注意,memset 将每个字节设置为一个值。它不能用于初始化多字节类型,如指针、int 对象或浮点对象,除非所需的值在每个字节中用相同的位表示(特别是零)。
  • void** 很可能是用于几乎任何目的的错误类型。如果您指向未知类型的“错位”数组,则可以使用void* - 这是一个分配为一维数组的二维数组,其索引在运行时计算。但是void* 不是一个有用的类型,因为你不能对它进行指针算术。也许您正在寻找uint8_t*。或者,您可以使用灵活的数组成员,这可能是您真正想要在这里做的。
  • @Lundin:问题中没有void,除了作为函数的返回类型,它只是void,而不是void**。你误读了vec**吗?

标签: c pointers matrix vector


【解决方案1】:

当您使用memset() 时,您只调用一次initvec()。所以所有元素都会指向 same 向量。

另外,memset() 将值分配给数组中的每个字节。但是你的行应该包含指针,而不是字节。

顺便说一句,您的代码泄漏了大量内存,因为您从未free() 行中的旧指针。您需要在致电realloc() 之前执行此操作。

【讨论】:

  • 谢谢。是否有像 memset 这样的函数可以处理指针而不是字节?也感谢您的提醒。我会解决的
  • 不,没有。即使有,你也会遇到我指出的第一个问题。
  • 好的。非常感谢。我才刚开始学习 c,所以显然我很烂,但我想每个人都从某个地方开始。
  • 不要自责。这是一个常见的错误。
  • 嗨,barmar 很抱歉打扰您,但我对您所说的导致内存泄漏的确切含义有点困惑。在我看来,它不只是重新分配内存,而且我认为它可以自己解决内存泄漏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多