有人可以解释为什么这不起作用吗?
int main()
{
float* x;
float a, b;
int num_vals = 10;
fill_in_x(&x, num_vals); // malloc is called and x is populated with values
a = x[0];
b = x[1] - x[0];
printf("%f\n", a);
printf("%f\n", b);
function_using_a_and_b(a, b); // The values of a and b used in this function
// don't match those calculated in main
}
void fill_in_x(float** x, int num_vals)
{
*x = (float*)malloc(num_vals * sizeof(float));
// Fill in values for x
}
void function_using_a_and_b(float a, float b)
{
printf("%f\n", a);
printf("%f\n", b);
}
重申注释中的内容,当我在一个单独的函数中为malloc动态分配x的内存时,尝试将几个值传递给另一个函数,这些值不能正确传递。感觉就像一个指向问题,但我认为我传递的是a和b的值,而不是地址。为了记录,我甚至尝试使用memcpy将值放在a和b中,但这也没有做到。
我确实通过传递a和b的地址然后在function_using_a_and_b中取消引用它来使它工作,但为什么上面的方法不起作用?
提前致谢。
答案 0 :(得分:3)
为了让malloc在你的fill_in_x()函数中工作,你需要将指针传递给函数,而不是指针的引用。关于传递引用和传递值之间的问题,传递值涉及函数制作变量的本地副本,而传递引用则是指针传递的更具体类型,通过here更好地解释。忽略它适用于C ++,因为对于你的问题,它的工作方式与C相同。
答案 1 :(得分:2)
你很可能在fill_in_x中做了一些不正确的事情。由于定义不在帖子中,我不能说什么,但它应该是这样的:
void fill_in_x(float** array) {
*array = (float*) malloc(10*sizeof(float));
}
(虽然返回已分配的内存是不好的形式,因为它经常会导致内存泄漏,例如代码中的内存泄漏。)
(响应fill_in_x):在visual studio上编译并运行此代码会产生预期的输出。
#include <stdio.h>
#include <stdlib.h>
void fill_in_x(float** x, int num_vals)
{
*x = (float*)malloc(num_vals * sizeof(float));
for(int i = 0; i < num_vals; ++i)
(*x)[i] = (i*2)+3;
}
void function_using_a_and_b(float a, float b)
{
printf("%f\n", a);
printf("%f\n", b);
}
int main()
{
float* x;
float a, b;
int num_vals = 10;
fill_in_x(&x, num_vals); // malloc is called and x is populated with values
a = x[0];
b = x[1] - x[0];
printf("%f\n", a);
printf("%f\n", b);
function_using_a_and_b(a, b); // The values of a and b used in this function
// don't match those calculated in main
}
写入:
3.000000
2.000000
3.000000
2.000000
所以我仍然不确定你的意思。我怀疑帖子中仍然缺少有问题的代码。
答案 2 :(得分:2)
这看起来像我期望的那样有效:
#include <stdlib.h>
#include <stdio.h>
void fill_in_x(float** x, int num_vals)
{
float* res = (float*)malloc(num_vals * sizeof(float));
*x = res;
// Fill in values for x
res[0] = 1.0;
res[1] = 4.0;
}
void function_using_a_and_b(float a, float b)
{
printf("%f\n", a);
printf("%f\n", b);
}
int main()
{
float* x;
float a, b;
int num_vals = 10;
fill_in_x(&x, num_vals); // malloc is called and x is populated with values
a = x[0];
b = x[1] - x[0];
function_using_a_and_b(a, b); // The values of a and b used in this function
// don't match those calculated in main
}
答案 3 :(得分:1)
您可以尝试调试函数fill_X,并在函数的主内部和内部观察f地址。
另一种方法是将fill_x函数更改为
float* fill_x(){
float* f = malloc(...);
//do stuff with f.
return f;
}
然后你必须释放那个记忆
float *f = fill_x();
//do stuff with f.
free(f);
答案 4 :(得分:0)
如果函数需要修改给定参数的值,则需要为其指定地址。否则它会在a和b中创建值的新本地副本并修改它们。
答案 5 :(得分:0)
如果有点奇怪的话,你所做的事情看起来是正确的。
我唯一担心的是你没有展示足够的fill_in_x代码,以便我们了解你正在填写的内容。
// Fill in values for x
这里有可能你做错了 - 很简单,因为你有两个需要思考的问题(float ** x)。
确保你正在做: -
(*x)[0] = 0;
(*x)[1] = 100;
... etc...
...而不是
x[0] = 0; // compiles, but overwrites the pointer with NULL...
..或
*(x[0]) = 0;
..或
*x[0] = 0;
当你调用function_using_a_and_b时更改a和b - 这很奇怪。您 正确地按值传递它们。你在这里使用什么编译器?
答案 6 :(得分:0)
为什么malloc x不在main中,所以你不会忘记稍后释放x,从而造成内存泄漏。我建议避免使用浮动**,这太混乱了。
答案 7 :(得分:0)
我的猜测是你的函数声明如下:
void fill_in_x(float* x);
当 应该时:
void fill_in_x(float** x);
使用你的声明,函数需要获得一个浮点指针,但你传递浮点指针x的地址 - 它就在堆栈的某个地方,因为这是局部变量所在的位置分配。
这意味着您在自己的调用堆栈上分配空间,结果显然可怕。 :)
答案 8 :(得分:0)
你可能正在使用
*x[0] = 3.0;
,当您确实需要使用
时 fill_in_x()
编辑:顺便说一句,C没有通过引用传递,它只是一个教学功能。您只需按值传递变量ADDRESSES,然后取消引用该值以获取原始变量。
答案 9 :(得分:0)
void fill_in_x(float** x, int num_vals)
{
*x = (float*)malloc(num_vals * sizeof(float));
for (int i = 0; i < num_vals; ++i) {
(*x)[i] = (float)i;
}
}
这也有效。让我想知道你的fill_in_x()是什么样的。代码没有任何问题。
答案 10 :(得分:0)
如最初编写的那样,调用范围时function_using_a_and_b()
范围内没有原型,因此编译器必须在传递float
之前将double
值提升为{{1}}。然后该函数以原型notataion编写,因此编译器可能不会注意到函数已经被双精度调用,即使原型符号允许它传递浮点数。这会在打印时产生奇怪的值。
我不相信编译器不会发现问题 - 但它可能会说明你所看到的。当然,如果函数在单独的源文件中,那么编译器就没有机会发现不匹配。