在 memset 之后未写入结构数组的值

Posted

技术标签:

【中文标题】在 memset 之后未写入结构数组的值【英文标题】:Values not written to struct array after memset 【发布时间】:2022-01-12 17:01:36 【问题描述】:

我已经编写了一个程序,该程序将值写入 c 中的结构数组,但似乎没有任何值写入结构数组。

在第一个代码块中,我实例化了一个结构数组并将该位置的内存设置为 0:

struct s_prob prob_values[(int) pow(n, 2)];
memset(prob_values, 0, sizeof(prob_values));

我在main之前声明的struct s_prob如下:

struct s_prob 
    int index;
    float probability;
    unsigned long count;
;

而我用来将值写入结构数组的代码如下:

int prob_count = 0;
for (int i = 0; i < n; i++) 
    for (int j = 0; j < n; j++) 
        printf("%d, %d, ", prob_count, prob_values[prob_count].index);
        prob_values[prob_count].index = (int) prob_count;
        prob_values[prob_count].probability = (float) pow((1.0 - p_x_error), n - i) * pow((1.0 - p_z_error), num_data_qubits - j) * pow(p_x_error, i) * pow(p_z_error, j);
        prob_values[prob_count].count = (unsigned long) pascal_triangle[n][i+j];
        prob_count++;
        printf("At index %d: prob: %e, count: %lu\n", prob_values[prob_count].index, prob_values[prob_count].probability, prob_values[prob_count].count);
    

第一个打印语句的格式是这样的,因为我想将索引的值与计数器进行比较,以确保它们相同。这是因为第二个 print 语句打印的值根本不是调用 memset 之前应该有的值。现在,根本没有写入任何值。

这是我在实施 memset 之前收到的输出:

0, 713, At index 0: prob: 0.000000e+00, count: 456
1, 0, At index 0: prob: 0.000000e+00, count: 0
2, 0, At index -890830848: prob: 6.235778e-43, count: 1914664608552
3, -890830848, At index 0: prob: 0.000000e+00, count: 0
4, 0, At index 0: prob: 0.000000e+00, count: 4112
5, 0, At index 0: prob: 0.000000e+00, count: 1914664608560
6, 0, At index 0: prob: 0.000000e+00, count: 1914664591506
7, 0, At index -890805472: prob: 6.235778e-43, count: 3372220617
8, -890805472, At index 0: prob: 0.000000e+00, count: 0
9, 0, At index -890830512: prob: 6.235778e-43, count: 0
10, -890830512, At index 73: prob: 0.000000e+00, count: 1023
11, 73, At index -890805472: prob: 6.235778e-43, count: 2533359767
12, -890805472, At index 201: prob: 0.000000e+00, count: 0
13, 201, At index 0: prob: 0.000000e+00, count: 0
14, 0, At index 0: prob: 0.000000e+00, count: 257
15, 0, At index 8: prob: 0.000000e+00, count: 0
16, 8, At index 4112: prob: 0.000000e+00, count: 4096
17, 4112, At index 2: prob: 0.000000e+00, count: 1914664583168
18, 2, At index 129: prob: 0.000000e+00, count: 140727915623501
19, 129, At index -890830848: prob: 6.235778e-43, count: 10
20, -890830848, At index 4096: prob: 0.000000e+00, count: 0
21, 4096, At index -890819760: prob: 6.235778e-43, count: 105920832884
22, -890819760, At index 0: prob: 4.203895e-45, count: 0
23, 0, At index 0: prob: 0.000000e+00, count: 4112
24, 0, At index 0: prob: 0.000000e+00, count: 0
25, 0, At index 0: prob: 0.000000e+00, count: 1914664591506
26, 0, At index 0: prob: 0.000000e+00, count: 3405775306
27, 0, At index 0: prob: 0.000000e+00, count: 2533359767
28, 0, At index 0: prob: 0.000000e+00, count: 0
29, 0, At index 0: prob: 0.000000e+00, count: 0
30, 0, At index 0: prob: 0.000000e+00, count: 2533359767
31, 0, At index 0: prob: 0.000000e+00, count: 0
32, 0, At index 4: prob: 0.000000e+00, count: 4294967295
33, 4, At index -919681840: prob: 4.590514e-41, count: 105920833784
34, -919681840, At index 0: prob: 0.000000e+00, count: 4096
35, 0, At index 1: prob: 0.000000e+00, count: 140727914045745
36, 1, At index 0: prob: 0.000000e+00, count: 4096
37, 0, At index 129: prob: 0.000000e+00, count: 140727915577344
38, 129, At index -890830848: prob: 6.235778e-43, count: 10
39, -890830848, At index 4096: prob: 0.000000e+00, count: 140727914045119
40, 4096, At index 0: prob: 0.000000e+00, count: 105920833188
41, 0, At index 0: prob: 4.203895e-45, count: 140727915775920
42, 0, At index 5: prob: 0.000000e+00, count: 140727914280046
43, 5, At index -983893456: prob: 4.591354e-41, count: 140727914527280
44, -983893456, At index 1: prob: 0.000000e+00, count: 4096
45, 1, At index 0: prob: 0.000000e+00, count: 140727914188698
46, 0, At index -983893456: prob: 4.591354e-41, count: 140727914179194
47, -983893456, At index 131: prob: 0.000000e+00, count: 1914664585312
48, 131, At index 10: prob: 0.000000e+00, count: 140727914254959
49, 10, At index 72: prob: 0.000000e+00, count: 140727914527280
50, 72, At index -983893456: prob: 4.591354e-41, count: 10
51, -983893456, At index 0: prob: 0.000000e+00, count: 4294967295
52, 0, At index 24576: prob: 0.000000e+00, count: 140702208911160
53, 24576, At index -919683005: prob: 4.590514e-41, count: 140727914527280
54, -919683005, At index -919683010: prob: 4.590514e-41, count: 140727914045745
55, -919683010, At index 0: prob: 0.000000e+00, count: 140727914188698
56, 0, At index -983893360: prob: 3.082857e-44, count: 0
57, -983893360, At index 0: prob: 0.000000e+00, count: 0
58, 0, At index 55: prob: 0.000000e+00, count: 140727914254959
59, 55, At index 0: prob: 0.000000e+00, count: 0
60, 0, At index -983893456: prob: 4.591354e-41, count: 18446744069414608896
61, -983893456, At index -1: prob: nan, count: 140702208924636
62, -1, At index -1453387905: prob: 1.254162e-42, count: 4611686018427387904
63, -1453387905, At index -1453348608: prob: 3.363116e-44, count: 4611686018427387904
64, -1453348608, At index -983893456: prob: 4.591354e-41, count: 140702208902446
65, -983893456, At index -1453348656: prob: 3.363116e-44, count: 140727914527280
66, -1453348656, At index -919683010: prob: 4.590514e-41, count: 5
67, -919683010, At index 16: prob: 0.000000e+00, count: 140702208901562
68, 16, At index 24576: prob: 0.000000e+00, count: 140727913971049
69, 24576, At index -1453348616: prob: 3.363116e-44, count: 20
70, -1453348616, At index -1453348616: prob: 3.363116e-44, count: 0
71, -1453348616, At index -1453348616: prob: 3.363116e-44, count: 4611686018427387904
72, -1453348616, At index 0: prob: 0.000000e+00, count: 0
73, 0, At index 0: prob: 0.000000e+00, count: 0
74, 0, At index 0: prob: 0.000000e+00, count: 20
75, 0, At index 20: prob: 0.000000e+00, count: 16
76, 20, At index 0: prob: 0.000000e+00, count: 1296
77, 0, At index 0: prob: 1.875000e+00, count: 140702208892796
78, 0, At index -919683010: prob: 4.590514e-41, count: 1
79, -919683010, At index 1074790400: prob: 0.000000e+00, count: 0
80, 1074790400, At index -61569: prob: nan, count: 64

虽然所有这些值在 memset 中都是 0,即使在嵌套 for 循环中设置了这些值之后也是如此。有谁知道我做错了什么?这些值应该写入结构,但似乎它们不会持续存在,只是在打印前回到 0。其余代码不需要任何解释,因为我认为我正在编写的值的计算与错误无关。该程序始终没有错误地退出,所以我不确定为什么它不能正常工作。谢谢!

【问题讨论】:

第一件事。永远不要使用pow 进行整数计算。 pow(n, 2) 可以轻松替换为 n*n 我认为这也是同样的事情。 pow 消耗的时钟周期是否比 n*n 多得多? 与时钟周期无关。 pow 正在执行浮点计算,这可能会产生不正确的结果,并且当转换回 int 时可能会导致开关(或更糟)的结果。 开枪,没错。我完全忘记了这一点。非常感谢! 【参考方案1】:

看起来好像是索引错误。由于 prob_count++ 出现在 print 语句之前,我只是把它放在之后,问题似乎已经消失了,一切都按照它应该的方式打印了。很奇怪,它没有抛出错误!

【讨论】:

为什么会报错? C 不会插入任何代码来检查你没有做错什么,比如引用一个不确定的值。 (无论如何,它是怎么知道的?)例如,使用 valgrind 来捕获这样的错误。 我认为如果我尝试访问数组的超出范围的索引,它至少会返回 0 以外的错误代码。另外,直到今天我才听说过 valgrind,所以感谢您的推荐!我肯定会调查的。 从什么返回错误代码?数组下标a[i] 提供数组aith 位置的任何内容。如果您没有设置该值,那么它是不确定的,但数组索引运算符不知道这一点。它甚至不知道i 是否在可能的索引范围内。它所做的只是将索引添加到a 的起始地址,并返回该内存位置中发生的任何内容。或者,如果这不是有效地址,则会出现段错误,如果i 超出范围,就会发生这种情况。但这个指数根本没有超出范围。您只是尚未设置值。【参考方案2】:

你正在增加prob_count然后打印。因此,您实际上并没有打印刚刚设置的值,而是打印下一个尚未设置的成员的内容。您在没有 memset 的情况下看到的是不确定的值。在 memset 之后,您会看到 0 值。

首先打印您更新的内容,然后递增。

【讨论】:

【参考方案3】:

问题出在这里:

        prob_count++;
        printf("At index %d: prob: %e, count: %lu\n", prob_values[prob_count].index, prob_values[prob_count].probability, prob_values[prob_count].count);

您不会打印刚刚分配的结构,而只打印下一个归零的结构。它还会在最后一次迭代中导致未定义的行为。

必须是:

        printf("At index %d: prob: %e, count: %lu\n", prob_values[prob_count].index, prob_values[prob_count].probability, prob_values[prob_count].count);
        prob_count++;

另外:

(int) pow(n, 2)

在处理整数时切勿使用浮点函数。只需这样做:

n * n

使用正确的尺寸类型。在int 中使用size_tssize_t 代替索引(如果索引可以为负数)

【讨论】:

以上是关于在 memset 之后未写入结构数组的值的主要内容,如果未能解决你的问题,请参考以下文章

关于memset问题,请问下列的值都可以吗

关于memset()

使用memset()要注意

裸机嵌入式 C++:将闪存写入 ram 时未定义对 memcpy 和 memset 的引用

memset上的程序崩溃?

memset