#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
он находится вне зоны действия. Но этот показатель вовсе не выходит за пределы диапазона. Вы просто еще не установили значение.