Значения, не записанные в массив структуры после набора memset

#c #struct

#c #структура

Вопрос:

Я написал программу, которая записывает значения в массив структур на языке си, но, похоже, ни одно из значений не записывается в массив структур.

В первом блоке кода я создаю экземпляр массива структур и устанавливаю для памяти в этом месте значение 0:

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

Структура s_prob, которую я объявляю перед main, выглядит следующим образом:

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

И код, который я использую для записи значений в массив структуры, выглядит следующим образом:

 int prob_count = 0; for (int i = 0; i lt; n; i  ) {  for (int j = 0; j lt; 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: %lun", prob_values[prob_count].index, prob_values[prob_count].probability, prob_values[prob_count].count);  } }  

Первый оператор печати отформатирован так, как он есть, потому что я хотел сравнить значения индекса со счетчиком, чтобы убедиться, что они совпадают. Это связано с тем, что значения, выводимые вторым оператором печати, были совсем не такими, какими они должны были быть до вызова 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  

В то время как все эти значения равны 0 в memset, даже после установки этих значений из вложенных циклов for. Кто-нибудь знает, что я делаю не так? Значения должны записываться в структуру, но, похоже, они не сохраняются и просто возвращаются к 0 перед печатью. Остальная часть кода не должна нуждаться в каких-либо объяснениях, так как я не думаю, что вычисление значений, которые я пишу, имеет какое-либо отношение к ошибке. Программа всегда завершается без ошибок, поэтому я не уверен, почему это работает неправильно. Спасибо!

Комментарии:

1. Перво-наперво. Никогда не используйте pow для целочисленных вычислений. pow(n, 2) может быть легко заменен n*n

2. Я думал, что это делает то же самое. Потребляет ли pow так много тактов больше, чем n*n?

3. Не имеет отношения к тактовому циклу. pow выполняет вычисления с плавающей запятой, которые могут привести к неточным результатам, а при обратном преобразовании int могут привести к включению-выключению (или худшим) результатам.

4. Стреляй, все правильно. Я совсем забыл об этом. Большое вам спасибо!

Ответ №1:

Проблема в том, что здесь:

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

Вы не печатаете структуру, которую только что назначили, только следующую, которая обнуляется. Это также приводит к неопределенному поведению на последней итерации.

Это должно быть:

 printf("At index %d: prob: %e, count: %lun", 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_t или ssize_t для индексов (если индекс может быть отрицательным)

Ответ №2:

Вы увеличиваете prob_count , а затем печатаете. Таким образом, на самом деле вы печатаете не только заданные значения, но и содержимое следующего элемента, который еще не был задан. То, что вы видите без memset, — это неопределенные значения. После memset вы увидите значения 0.

Сначала распечатайте то, что вы обновили, а затем увеличьте.

Ответ №3:

Похоже, что это была ошибка индексирования. Поскольку prob_count появился до инструкции print, я просто поставил ее после, и проблема, похоже, исчезла, и все печатается так, как должно. Очень странно, что он не выдал ошибку, хотя!

Комментарии:

1. С чего бы ему выдавать ошибку? C не вставляет никакого кода, чтобы проверить, не делаете ли вы что-то неправильно, например, ссылаетесь на неопределенное значение. (В любом случае, откуда ему знать?) Используйте valgrind, например, для обнаружения подобных ошибок.

2. Я думал, что он, по крайней мере, вернет код ошибки, отличный от 0, если я попытаюсь получить доступ к индексу вне диапазона для массива. Кроме того, я никогда не слышал о valgrind до сегодняшнего дня, так что спасибо за рекомендацию! Я определенно займусь этим вопросом.

3. Верните код ошибки от чего? Индекс массива a[i] предоставляет все, что находится в i t-й позиции в массиве a . Если вы не установили это значение, то оно неопределенно, но оператор индекса массива об этом не знает. Он даже не знает, находится ли i он в диапазоне возможных индексов. Все, что он делает, — это добавляет индекс к стартовому адресу a и возвращает все, что находится в этой области памяти. Или он сегментируется, если это неверный адрес, что может произойти, если i он находится вне зоны действия. Но этот показатель вовсе не выходит за пределы диапазона. Вы просто еще не установили значение.