简单的C指针问题
自从我完成任何 C 编程以来,已经有很长一段时间了,而且我一直在思考一个应该是非常简单的问题。我有一个简单的函数,它调用另一个函数,该函数在堆上分配一些内存,用一个结构填充它并返回一个指针。一切看起来都很好,除了当指针返回到调用函数时,它的地址已损坏。
这是相关代码:
被调用函数:
struct server_type *init_gwserver(Cfg* cfg)
{
struct server_type *res = NULL;
// Lots of irrelevant code removed here - doesn't reference res.
res = gw_malloc(sizeof(struct server_type));
gw_assert(res != NULL);
res->server_start = gwserver_start; // Pointer to a function
res->server_stop = gwserver_stop; // Pointer to another function
return res;
}
调用函数:
struct server_type *do_init_server(Cfg *cfg)
{
struct server_type *res = NULL;
res = (struct server_type *)init_gwserver(cfg);
if (res) {
return res;
}
}
好的,这就是奇怪之处。当“res”返回到调用函数时,指针指向的地址发生变化,并成为无效的内存引用。下面是 GDB 的快速浏览。评论(//...)是我的...
Breakpoint 1, init_gwserver (cfg=0x100214e30) at init_gwserver.c:339
339 res->server_stop = gwserver_stop;
(gdb) print /x res
$18 = 0x100215b10
// Pointer above looks fine and seems to be a valid address
(gdb) p *res
$14 = {
type = 0x100215460,
sql_enter = 0x100003820 <gwserver_start>,
sql_leave = 0x100005ae0 <gwserver_stop>,
}
// Contents of the pointer are looking great
(gdb) next
340 return res;
(gdb) print /x res
$19 = 0x100215b10
// Pointer is unchanged - should return this value just fine.
(gdb) next
do_init_server (cfg=0x100214e30) at init_server.c:52
52 if (res) {
(gdb) print /x res
$20 = 0x215b10
// WOW - what the hell happened to the address pointed to by res? It lost the leading 100.
(gdb) p *res
Cannot access memory at address 0x215b10
// Yep, it's definitely now an invalid pointer. Crash time...`
这可能是非常非常简单的事情,但我无法指出它。有人有建议吗?
谢谢! 托比.
It's been a long (long...) time since I've done any C programming and I'm stuck on what should be a really simple issue. I have a simple function that's calling another function that is allocating some memory on the heap, populating it with a structure and returning a pointer back. Everything looks great, except when the pointer is returned to the calling function, it's address is corrupted.
Here's the relevant code:
Called function:
struct server_type *init_gwserver(Cfg* cfg)
{
struct server_type *res = NULL;
// Lots of irrelevant code removed here - doesn't reference res.
res = gw_malloc(sizeof(struct server_type));
gw_assert(res != NULL);
res->server_start = gwserver_start; // Pointer to a function
res->server_stop = gwserver_stop; // Pointer to another function
return res;
}
Calling function:
struct server_type *do_init_server(Cfg *cfg)
{
struct server_type *res = NULL;
res = (struct server_type *)init_gwserver(cfg);
if (res) {
return res;
}
}
OK, here's the weirdness. When "res" is returned to the calling function, the address the pointer is pointing to changes, and becomes an invalid memory reference. Here's a quick run through with GDB. Comments (//...) are mine...
Breakpoint 1, init_gwserver (cfg=0x100214e30) at init_gwserver.c:339
339 res->server_stop = gwserver_stop;
(gdb) print /x res
$18 = 0x100215b10
// Pointer above looks fine and seems to be a valid address
(gdb) p *res
$14 = {
type = 0x100215460,
sql_enter = 0x100003820 <gwserver_start>,
sql_leave = 0x100005ae0 <gwserver_stop>,
}
// Contents of the pointer are looking great
(gdb) next
340 return res;
(gdb) print /x res
$19 = 0x100215b10
// Pointer is unchanged - should return this value just fine.
(gdb) next
do_init_server (cfg=0x100214e30) at init_server.c:52
52 if (res) {
(gdb) print /x res
$20 = 0x215b10
// WOW - what the hell happened to the address pointed to by res? It lost the leading 100.
(gdb) p *res
Cannot access memory at address 0x215b10
// Yep, it's definitely now an invalid pointer. Crash time...`
This is probably something really, really simple, but I can't put my finger on it. Anyone got suggestions?
Thanks!
Toby.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此转换看起来很可疑:
(struct server_type *)init_gwserver(cfg)
。如果需要进行强制转换才能使代码编译,则表明调用站点没有为
init_gwserver
可见的正确原型。如果没有可见的原型,编译器将假设该函数返回一个
int
。当返回值被检索为不是的东西时,根据实现的不同,它的值可能会被破坏,并且当转换回指针时,信息可能已经不可挽回地丢失。强制转换应该不是必需的,如果删除它会导致编译错误,则表明您需要在您之前添加(或
#include
)init_gwserver
的正确原型尝试调用它。This cast looks suspicious:
(struct server_type *)init_gwserver(cfg)
.If the cast is necessary to make the code compile then it indicates that there is not a correct prototype visible for
init_gwserver
at the call site.If there is no prototype visible, the compiler will make the assumption that the function returns an
int
. When the return value is retrieved as something that it is not, depending on the implementation, its value may be corrupted and when converted back to a pointer information may have been irretrievably lost.The cast should not be necessary and if removing it causes a compile error it indicates that you need to add (or
#include
) a correct prototype forinit_gwserver
before the point where you attempt to call it.