通过结构指针功能不能正常工作 [英] passing struct pointer to functions not working

查看:186
本文介绍了通过结构指针功能不能正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

动机:传递结构给函数比如我们可以在任何功能改变和检索任何函数任意值

Motive: Passing struct to functions such as we can change it in any function and retrieve any value in any function.

我拾起这个code:<一href=\"http://cboard.cprogramming.com/c-programming/126381-passing-structure-reference-through-4-functions.html#post942397\" rel=\"nofollow\">http://cboard.cprogramming.com/c-programming/126381-passing-structure-reference-through-4-functions.html#post942397

我调整这一点,那就是:

I tweaked it a little and here it is:

struct_passing.h

typedef struct thing {
    char *x;
}thing_t;

struct_passing.c


#include <stdio.h>
#include "struct_passing.h"

void f4(thing_t *bob) {
    bob->x = "changed";
}

void f3(thing_t *bob) {
    f4(bob);
        printf("inside f3 x: %s\n", bob->x);
}

void f2(thing_t *bob) {
    f3(bob);
}

void f1(thing_t *bob) {
    f2(bob);
}

int main(void) {
    thing_t foo;
    foo.x = "same";
    printf("Before: %s\n", foo.x);
    f1(&foo);
    printf("After: %s\n", foo.x);
    return 0;
}

它适用于** GCC 4.4.3版本预期在Ubuntu

It works as expected on **gcc version 4.4.3 on ubuntu

$ gcc -o struct struct_passing.c 
$ ./struct
Before: same
inside f3 x: changed
After: changed

但在FreeBSD的gcc版本4.2.1,我不能检索的bob-> X更改值。我不明白里面F3 X:修改。我得到的垃圾吧。

为什么?

推荐答案

一切看起来就好了我。它总是有益的在调试器中运行一个小样本的程序是这样,看看什么是真正发生的事情。如果你不知道GDB,现在是一个伟大的时刻开始。我创建struct_passing从code [CH],让我们一起来看看:

Everything looks just fine to me. It's always instructive to run a small sample program like this in the debugger, to see what's really happening. If you don't know gdb, now is a great time to start. I've created struct_passing.[ch] from your code, let's have a look:

[wes@eeegor ~]$ gcc -v
Using built-in specs.
Target: i386-undermydesk-freebsd
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 4.2.1 20070719  [FreeBSD]

是啊,相同的编译器。调试编译:

Yup, same compiler. Compile for debugging:

[wes@eeegor ~/src]$ cc -g -o struct struct_passing.c

和运行它:

[wes@eeegor ~/src]$ gdb struct
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-marcel-freebsd"...

OK,我们可能想知道什么是主从()上发生的事情,所以......

OK, we probably want to know what's happening from main() on, so...

(gdb) b main
Breakpoint 1 at 0x80484c0: file struct_passing.c, line 21.
(gdb) run
Starting program: /usr/home/wes/src/struct

Breakpoint 1, main () at struct_passing.c:21
21      int main(void) {

我们将主要使用(S)TEP步入功能,和(n)分机跨过我们不希望看到的内部功能,如printf()。我们也可能偶尔(P)RINT东西。

We'll mostly use (s)tep to step into functions, and (n)ext to step over functions we don't want to see the inside of, like printf(). We may also occasionally (p)rint something.

(gdb) n
main () at struct_passing.c:23
23          foo.x = "same";

我们还没有执行这一行,所以如果我们看看富,它可能会包含垃圾:

We haven't yet executed this line, so if we look at foo, it will probably contain garbage:

(gdb) p foo
$1 = {x = 0x80482c5 "\203Ä\fÃ"}

是啊,正如所料,x指向一些垃圾串。这是因为foo,并且通过扩展foo.x,得到了在main()函数在栈上创建的,并且堆栈只是有任何随机的垃圾被绕前离开了。

Yup, as expected, x points to some garbage string. That's because foo, and by extension foo.x, got created on the stack in the main() function, and the stack just has whatever random junk was left around before.

(gdb) n
24          printf("Before: %s\n", foo.x);
(gdb) n
Before: same
25          f1(&foo);
(gdb) s
f1 (bob=0xbfbfec40) at struct_passing.c:18
18          f2(bob);
(gdb) p bob
$2 = (thing_t *) 0xbfbfec40

所以,我们踏入F1(),看看我们已经正确地传递foo的地址到函数。请注意如何GDB(P)RINT函数总是知道它的打印类型?在这种情况下,看到该结构的地址不是非常有用的,这样:

So we step into f1() and see that we have correctly passed the address of foo into the function. Notice how the gdb (p)rint function always knows the type of what it's printing? In this case, seeing the address of the structure isn't very useful, so:

(gdb) p *bob
$3 = {x = 0x804857c "same"}

呵呵,好,结构仍然看起来像它应该。让我们继续下去,直到我们改变它:

Oh, good, the structure still looks like it should. Let's keep going until we change it:

(gdb) s
f2 (bob=0xbfbfec40) at struct_passing.c:14
14          f3(bob);
(gdb) p *bob
$4 = {x = 0x804857c "same"}
(gdb) s
f3 (bob=0xbfbfec40) at struct_passing.c:9
9           f4(bob);
(gdb) p *bob
$5 = {x = 0x804857c "same"}
(gdb) s
f4 (bob=0xbfbfec40) at struct_passing.c:5
5           bob->x = "changed";

记住,我们还没有执行第5行还,所以鲍勃仍然应该是相同的:

Remember, we haven't executed line 5 yet, so "bob" should still be the same:

(gdb) p *bob
$6 = {x = 0x804857c "same"}

是啊,让我们执行的5号线,再看看:

Yup, so let's execute line 5 and look again:

(gdb) n
6       }
(gdb) p *bob
$7 = {x = 0x8048563 "changed"}

所以,鲍勃没有得到改变。让我们继续,看看它是否在改变仍然高达main()的:

So "bob" did get changed. Let's keep going and see if it's still changed up in main():

(gdb) n
f3 (bob=0xbfbfec40) at struct_passing.c:10
10              printf("inside f3 x: %s\n", bob->x);
(gdb) n
inside f3 x: changed
11      }
(gdb) n
f2 (bob=0xbfbfec40) at struct_passing.c:15
15      }
(gdb) n
f1 (bob=0xbfbfec40) at struct_passing.c:19
19      }
(gdb) n
main () at struct_passing.c:26
26          printf("After: %s\n", foo.x);
(gdb) n
After: changed
27          return 0;

所以我们得到了我们的预期。在这一点上,我们即将从main()的返回,最好只让调试器继续让你不通过一半的C运行时启动code的尾部走:

So we got what we expected. At this point, we're about to return from main(), it's best to just let the debugger continue so you don't half to walk through the tail end of the C runtime startup code:

(gdb) c
Continuing.

Program exited normally.
(gdb) Quit
(gdb)

让我们退出调试并运行正常,以确保我们得到的结果相同。这将是非常奇怪的,如果我们没有......

Let's exit the debugger and run it normally to make sure we get the same output. It would be really weird if we didn't...

(gdb) q
[wes@eeegor ~/src]$ ./struct
Before: same
inside f3 x: changed
After: changed

噢,太好了,星星依然闪闪发光。我不知道你的情况发生了什么事,让我们尝试编译像你一样并运行它:

Oh, good, the stars are still shining. I'm not sure what happened in your case, let's try compiling as you did and run it:

[wes@eeegor ~/src]$ gcc -o struct struct_passing.c
[wes@eeegor ~/src]$ ./struct
Before: same
inside f3 x: changed
After: changed

所以,现在,让我们来改善你的bug报告。给我们的'的uname -a,GCC -v和LD -v输出,使我们能找出你使用什么系统。另请阅读上的软件乔尔的文章(S)关于如何写一个bug报告。 :)

So now, let's improve your bug report. Give us the output of 'uname -a', 'gcc -v', and 'ld -v' so we can find out exactly what system you're using. Also read the 'Joel on Software' article(s) about how to write a bug report. :)

这篇关于通过结构指针功能不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆