我只是好奇 - 为什么C允许你在函数期望指针时传递解除引用的指针。这是一个例子:
typedef struct {
char message[255];
} Bla;
// so he's the function that's expecting the pointer
void cool_function(Bla *_bla) {
}
Bla *woot = (Bla *)malloc(2 * sizeof(Bla));
woot[0] = (Bla) {
.message = "bla bla bla"
};
// woot itself is a pointer, but it's getting dereferenced when I am adding [0]
cool_function(woot[0]);
现在编译很好,但是当我去实际使用_bla(即_bla-> what),BAM,运行时错误。
所以这让我感到困惑 - 如果它通过值传递给这个显然需要指针的函数会发生什么呢?为什么甚至编译?
我对C很新,所以请不要跳过我。 :/
*更新*
很抱歉没有提及,但这是Pebble Watch的应用程序,它使用特殊版本的gcc用于特定的臂处理器(arm-cs-tools)。
*更新2 *
我想我发现了为什么这样做。函数'cool_function'实际上是在一个单独的文件中,当我在标题中声明了该函数时,它只用void cool_function()
声明 - 忘了包含Bla *_bla
。但定义是void cool_function(Bla *_bla)
。混淆编译器完全是我的错。
答案 0 :(得分:4)
您应该收到编译器错误:
error: passing 'Bla' to parameter of incompatible type 'Bla *'; take the address with &
cool_function(woot[0]);
如果您使用gcc或clang,请尝试使用-WError和-Wall选项编译程序。
答案 1 :(得分:1)
C将不会出现编译错误,因为它缺少类型检查。在您的示例中,如果从系统的角度来看值woot[]
是正确的,它甚至可能不会给出任何运行时错误
答案 2 :(得分:1)
你需要这样做:
cool_function(&woot[0]);
&在这种情况下,运算符创建引用。所以你要传递给woot [0]
的引用请注意,这意味着cool_function()现在可以改变woot [0]的内容。如果这是不希望的,您可能想要进行某种复制操作。
例如,你可以拥有一个函数,它将Bla *复制到一个新的Bla *实例中 - 这实现了有效的传值。诀窍是你必须复制。可选地,您可以使该函数采用const Bla * - 这样就不应该在技术上改变值。
答案 3 :(得分:1)
我已经拿走了你的代码并从中制作了一个完整的主文件:
#include <pebble.h>
typedef struct {
char message[255];
} Bla;
// so he's the function that's expecting the pointer
void cool_function(Bla *_bla) {
}
int main() {
Bla *woot = (Bla *)malloc(2 * sizeof(Bla));
woot[0] = (Bla) {
.message = "bla bla bla"
};
// woot itself is a pointer, but it's getting dereferenced when I am adding [0]
cool_function(woot[0]);
}
这是我尝试使用Pebble SDK 2.0.0编译时得到的结果:
./src/test.c: In function 'main':
../src/test.c:20:3: error: incompatible type for argument 1 of 'cool_function'
../src/test.c:8:6: note: expected 'struct Bla *' but argument is of type 'Bla'
所以看起来你的问题的评论都是正确的。您使用的是哪个版本的SDK?