gpt4 book ai didi

c - 更改宏值时出现段错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:15:29 25 4
gpt4 key购买 nike

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#define len 10
#define hi 10

void transpose(double (*matrix)[len][hi]);

int main() {
srand(time(NULL));
double (*matrix)[len][hi] = (double (*)[len][hi])malloc(sizeof(double[len][hi]));
double delimo, delitel;
for(int i = 0; i < len; i++){
for(int j = 0; j < hi; j++){
delimo = rand()%(len * hi);
delitel = rand()%(len * hi);
*matrix[i][j] = delimo/++delitel;
printf(" %5.2lf ", *matrix[i][j]);
}
puts("");
}
puts("Transpose: ");
transpose(matrix);
for(int i = 0; i < len; i++){
for(int j = 0; j < hi; j++){
printf(" %5.2lf ", *matrix[i][j]);
}
puts("");
}
free(matrix);

}

void transpose(double (*matrix)[len][hi]){
double (*Tmatrix)[len][hi] = (double (*)[len][hi])malloc(sizeof(double[len][hi]));
for(int i = 0; i < len; i++){
for(int j = 0; j < hi; j++){
*Tmatrix[i][j] = *matrix[j][i];
}
}
for(int i = 0; i < len; i++){
for(int j = 0; j < hi; j++){
*matrix[i][j] = *Tmatrix[i][j];
}
}
free(Tmatrix);
}

任务是分配一个二维数组,然后用一个函数对其进行转置,并通过一个函数调用将转置矩阵复制到原始矩阵中。矩阵的维度由宏设置,它们也在一些循环中和分配 2 个矩阵时使用。然而出于某种奇怪的原因,如果我决定更改它们,就会出现段错误。唯一从未崩溃的是 len = hi = 10 。在任何其他情况下,程序崩溃的几率均高于平均水平。

最佳答案

问题中显示的代码给出了我的构建 Valgrind conniptions 因为它没有正确使用指向矩阵的指针表示法。当独立运行时(不在 Valgrind 下)它似乎可以工作,但输出矩阵不是输入矩阵的转置——因为数据没有被正确访问。这是我得到的虚假输出的一个例子。您可以看到“转置”矩阵中索引为 0,1 和 1,0 的元素与原始矩阵中的元素无关。

  1.24   2.64   0.17   0.49  22.25   4.30   0.71   1.12   1.03   2.31 
1.39 7.18 0.40 0.44 4.30 0.17 0.62 12.67 0.34 9.10
2.85 0.69 3.50 1.58 0.77 0.04 0.26 0.79 0.24 1.59
16.00 0.14 0.12 0.56 1.68 0.08 0.69 0.13 2.51 1.74
5.50 0.96 0.45 1.00 0.00 0.84 0.97 0.40 2.14 0.67
2.00 0.14 1.84 0.88 1.26 0.21 0.70 0.30 1.74 0.60
2.04 1.00 0.35 0.12 0.00 0.65 1.21 0.18 0.52 9.70
1.19 1.08 0.88 1.71 0.88 0.21 1.74 0.70 0.44 1.23
1.38 0.69 0.12 0.14 4.18 3.17 0.06 7.10 8.00 1.52
0.16 6.07 0.81 0.49 0.14 1.37 4.00 0.93 0.98 1.48
Transpose:
1.24 1.24 2.64 0.17 0.49 22.25 4.30 0.71 1.12 1.03
-2.00 1.39 1.39 2.85 16.00 5.50 2.00 2.04 1.19 1.38
0.17 2.85 0.69 0.69 0.14 0.96 0.14 1.00 1.08 0.69
0.49 16.00 0.14 0.12 0.12 0.45 1.84 0.35 0.88 0.12
22.25 5.50 0.96 0.45 1.00 1.00 0.88 0.12 1.71 0.14
4.30 2.00 0.14 1.84 0.88 1.26 1.26 0.00 0.88 4.18
0.71 2.04 1.00 0.35 0.12 0.00 0.65 0.65 0.21 3.17
1.12 1.19 1.08 0.88 1.71 0.88 0.21 1.74 1.74 0.06
1.03 1.38 0.69 0.12 0.14 4.18 3.17 0.06 7.10 7.10
2.31 0.16 6.07 0.81 0.49 0.14 1.37 4.00 0.93 0.98

下面的代码适用于方阵。不同之处在于指向矩阵的指针在应用下标 ((*matrix)[i][j]) 之前取消引用,而不是在 (*matrix[i][j ]).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define len 10
#define hi 10

void transpose(double (*matrix)[len][hi]);

int main(void)
{
srand(time(NULL));
double (*matrix)[len][hi] = (double (*)[len][hi])malloc(sizeof(double[len][hi]));
double delimo, delitel;
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
delimo = rand() % (len * hi);
delitel = rand() % (len * hi);
(*matrix)[i][j] = delimo / ++delitel;
printf(" %5.2lf ", (*matrix)[i][j]);
}
puts("");
}
puts("Transpose: ");
transpose(matrix);
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
printf(" %5.2lf ", (*matrix)[i][j]);
}
puts("");
}
free(matrix);
}

void transpose(double (*matrix)[len][hi])
{
double (*Tmatrix)[len][hi] = (double (*)[len][hi])malloc(sizeof(double[len][hi]));
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
(*Tmatrix)[i][j] = (*matrix)[j][i];
}
}
for (int i = 0; i < len; i++)
{
for (int j = 0; j < hi; j++)
{
(*matrix)[i][j] = (*Tmatrix)[i][j];
}
}
free(Tmatrix);
}

示例输出:

  0.98   0.90   0.16   0.08   0.48   1.71   0.53   0.24   2.28   1.79 
0.73 0.36 2.00 3.27 0.29 1.25 19.40 1.60 0.56 0.00
3.00 10.50 1.81 1.56 1.11 0.78 1.53 0.71 1.27 0.93
2.10 0.56 2.34 1.48 0.81 2.16 0.47 0.16 7.62 0.91
0.93 2.48 0.15 0.71 1.09 0.73 0.58 0.48 1.13 0.99
0.59 0.72 8.75 2.19 61.00 1.41 2.08 0.83 0.65 0.16
0.42 1.13 0.85 1.00 3.00 0.55 0.33 1.67 0.44 0.69
0.08 1.17 0.25 0.92 1.04 0.17 1.77 1.95 0.50 0.90
2.28 0.35 0.41 1.27 0.80 3.36 0.29 0.13 3.88 0.39
0.64 0.50 0.40 0.15 0.45 0.78 0.31 1.48 1.50 1.06
Transpose:
0.98 0.73 3.00 2.10 0.93 0.59 0.42 0.08 2.28 0.64
0.90 0.36 10.50 0.56 2.48 0.72 1.13 1.17 0.35 0.50
0.16 2.00 1.81 2.34 0.15 8.75 0.85 0.25 0.41 0.40
0.08 3.27 1.56 1.48 0.71 2.19 1.00 0.92 1.27 0.15
0.48 0.29 1.11 0.81 1.09 61.00 3.00 1.04 0.80 0.45
1.71 1.25 0.78 2.16 0.73 1.41 0.55 0.17 3.36 0.78
0.53 19.40 1.53 0.47 0.58 2.08 0.33 1.77 0.29 0.31
0.24 1.60 0.71 0.16 0.48 0.83 1.67 1.95 0.13 1.48
2.28 0.56 1.27 7.62 1.13 0.65 0.44 0.50 3.88 1.50
1.79 0.00 0.93 0.91 0.99 0.16 0.69 0.90 0.39 1.06

您不能就地转置非方阵。如果您有一个 nxm 矩阵作为输入,则转置是一个 mxn 矩阵。在分配非转置的地方分配转置矩阵可能是最简单的,然后将两个矩阵都传递给转置函数。请注意使用 *matrix 将指向矩阵的指针作为矩阵传递给函数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void transpose(int rows, int cols, double matrix[rows][cols], double result[cols][rows]);
void print_matrix(const char *tag, int rows, int cols, double matrix[rows][cols]);

int main(void)
{
srand(time(NULL));
int cols = 10;
int rows = 8;
double (*matrix)[rows][cols] = malloc(sizeof(double[rows][cols]));
double (*result)[cols][rows] = malloc(sizeof(double[cols][rows]));
if (matrix == 0 || result == 0)
{
fprintf(stderr, "failed to allocate memory\n");
exit(EXIT_FAILURE);
}

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
double delimo = rand() % (rows * cols);
double delitel = rand() % (rows * cols) + 1;
(*matrix)[i][j] = delimo / delitel;
}
}

print_matrix("original", rows, cols, *matrix);
transpose(rows, cols, *matrix, *result);
print_matrix("transpose", cols, rows, *result);

free(matrix);
free(result);
return 0;
}

void print_matrix(const char *tag, int rows, int cols, double matrix[rows][cols])
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf(" %5.2f ", matrix[i][j]);
putchar('\n');
}
}

void transpose(int rows, int cols, double matrix[rows][cols], double result[cols][rows])
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
result[j][i] = matrix[i][j];
}
}
}

示例输出:

original (8x10):
0.84 0.92 0.18 1.97 4.54 31.00 1.59 0.11 0.35 0.07
0.96 3.19 1.00 4.86 3.25 3.50 2.65 1.07 0.24 0.77
6.00 0.13 0.40 1.04 0.99 0.88 1.24 0.67 3.07 12.00
1.89 0.48 0.72 0.55 0.26 0.64 0.55 0.09 0.30 0.98
0.51 0.86 0.85 0.33 1.44 0.89 2.38 2.21 0.27 2.12
6.40 1.71 2.83 1.61 0.76 0.13 0.81 1.48 1.13 0.51
0.79 0.69 0.57 1.10 1.00 1.31 0.68 1.95 1.42 0.46
0.00 0.43 1.64 0.88 1.03 0.14 0.35 1.78 0.86 2.82
transpose (10x8):
0.84 0.96 6.00 1.89 0.51 6.40 0.79 0.00
0.92 3.19 0.13 0.48 0.86 1.71 0.69 0.43
0.18 1.00 0.40 0.72 0.85 2.83 0.57 1.64
1.97 4.86 1.04 0.55 0.33 1.61 1.10 0.88
4.54 3.25 0.99 0.26 1.44 0.76 1.00 1.03
31.00 3.50 0.88 0.64 0.89 0.13 1.31 0.14
1.59 2.65 1.24 0.55 2.38 0.81 0.68 0.35
0.11 1.07 0.67 0.09 2.21 1.48 1.95 1.78
0.35 0.24 3.07 0.30 0.27 1.13 1.42 0.86
0.07 0.77 12.00 0.98 2.12 0.51 0.46 2.82

Valgrind给这两者一个干净的健康证明。原始代码导致 Valgrind 报告大量错误,例如:

==33404== Signal 11 being dropped from thread 0's queue

我不得不从另一个终端窗口终止该运行。

关于c - 更改宏值时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52441516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com