c - memset 将一些元素设置为 *almost* 零或 nan

标签 c windows-subsystem-for-linux

我有行 memset(C, 0, N*M);,其中 C 是 double 矩阵。 (我正在使用 WSL。)

但是,如果我查看 gdb,矩阵中的某些元素被设置为 -nan(0xffffffffffff8),而其他元素被设置为例如 9.0096750001652956e-314

第一个没有给出任何错误,但是 += 似乎没有改变任何东西(或者至少似乎没有让 nan 东西消失),而第二个是如果元素未更改或只有 += 0 的问题,因为比较 if (0 == C[i][j]) 会失败。

如果我手动将值设置为 0,则根本不会出现这些问题。

这是 WSL 的东西,还是关于 memset 的东西我不明白?

最佳答案

您没有完全初始化矩阵:memset() 需要一些字节。假设矩阵布局是线性的,无论是一维还是二维,您应该清除 sizeof(double) * N * M 字节。

如果您的矩阵定义为二维数组,您可以这样写:

#define N 10
#define M 20
        double C[N][M];
        memset(C, 0, sizeof C);

如果矩阵作为函数参数接收,你实际上得到一个指针,所以你必须更加小心:

void clear_matrix(double C[N][M]) {
    memset(C, 0, sizeof(*C) * N);
}

或者可能更具可读性:

void clear_matrix(double C[N][M]) {
    memset(C, 0, sizeof(C[0][0]) * N * M);
}

或者简单地说,如 Lundin 所建议的那样,但如果矩阵元素类型发生变化,则可能会中断:

void clear_matrix(double C[N][M]) {
    memset(C, 0, sizeof(double[N][M]);
}

但是请注意,memset() 会将矩阵数据清除为所有位为零,如果系统使用 IEEE-754 表示,但不是完全可移植的。可移植版本将使用嵌套循环和 good compiler如果适用于目标系统,将生成相同的 memset 调用或内联代码:

#include <stddef.h>

#define N 10
#define M 20

void clear_matrix(double C[N][M]) {
    for (size_t i = 0; i < N; i++) {
        for (size_t j = 0; j < M; j++) {
             C[i][j] = 0.0;
        }
    }
}

关于c - memset 将一些元素设置为 *almost* 零或 nan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71035342/

相关文章:

ubuntu - 在 WSL for Docker 18.03 中将卷挂载到容器

ubuntu - 能够在 WSL Ubuntu 上运行的 Kami(Bluespec 的 Coq 框架)的正确设置是什么?

linux - 在 WSL 上链接 Arm 时出现错误 "__aeabi_unwind_cpp_pr0"

c - 来自单个输入的多个 scanf

c - C 编程中如何调用变量指定 printf 的格式

c++ - 为什么我们需要连接超时管理

c++ - 我如何摆脱这些警告?

c - gl.h 包含在 glew 之前,但 GLFW 需要 gl.h

windows - Windows 上的 Ubuntu 上的 Bash 会在启动后自动在后台运行吗

python - WSL :/usr/bin/env: ‘python’ : No such file or directory