关于C#:Printf更改内存值

Printf changing memory values

我正在尝试做一些定点向量的数学运算,似乎每当我打印任何东西时,似乎都无关紧要。我的向量值改变了。代码是使用Zilog的ZDSII Developer Studio编译的。

我有一个这样定义的结构

1
2
3
4
typedef struct {
    long x;
    long y;
} vector;

结构中的值在函数中初始化

1
2
3
4
void initVector( vector * vec, int x, int y ) {
    vec -> x = (long) x << 14;
    vec -> y = (long) y << 14;
}

在我的主要功能中

1
2
3
4
5
6
7
8
9
10
int main() {
    vector * vector1;

    initVector( vector1, 1, 2 );
    printf("foo" ); // this prints alright
    printf("%d , %d", vector1 -> x >> 14, vector1 -> y >> 14 ); //garbage
    ...

    ...
}

打印垃圾。这些值将根据printf之前的printf语句的数目而改变,在printf中我实际打印这些值。


你使用了未初始化的vector1

1
2
3
vector * vector1;

initVector( vector1, 1, 2 );

因此,initVector调用了未定义的行为。

成功

1
2
vector vector1;
initVector(&vector1, 1, 2);

1
vector * vector1 = malloc(sizeof *vector1);


您没有为vector1分配内存来指向,因此initVector()中的代码会覆盖随机的内容,导致未定义的行为。

您的代码应该是:

1
2
3
4
5
vector vector1;  /* NOT a pointer! */

initVector(&vector1, 1, 2);
printf("foo" ); // this prints alright
printf("%d , %d", vector1.x >> 14, vector1.y >> 14 );

为了使API更易于使用,考虑将vector结构作为一个值,并执行以下操作:

1
2
3
4
5
6
7
vector initVector(int x, int y)
{
  vector v;
  v.x = (long) x << 14;
  v.y = (long) y << 14;
  return v;
}

这使得代码更易于使用,并消除了此特定错误的风险:

1
2
3
4
5
6
int main(void)
{
  vector vector1 = initVector(1, 2);
  printf("%d, %d
"
, vector1.x >> 14, vector1.y >> 14);
}


vector1分配内存,例如:

1
2
3
4
5
6
7
int main()
{
    vector vector1;

    initVector( &vector1, 1, 2 );
    printf("%d , %d", vector1.x >> 14, vector1.y >> 14 ); //no garbage :-)
}