问题
I have a bug in which an incorrect value gets passed as an argument to a function in a C program. The way it works is, I declare a static pointer to a typedef-ed data structure as a global variable. There is an initialization function where this variable is initialized. This function allocates memory, initializes data fields and returns the pointer. Something like this:
static my_type *my_ptr;
...
void init(void){
my_ptr = init_my_type();
}
The function init_my_type
is pretty straight forward:
void *init_my_type(void){
my_type *x = malloc(sizeof(my_type);
x->arg1 = 0;
... // more field initializations
return x;
}
Later on I use my_ptr
as an argument to another function:
void do_stuff(void){
func(my_ptr);
}
The problem I have is that I seg fault in the guts of func
when some of the data in the data structure that my_ptr
points to is accessed.
When I run the debugger I get a nice looking hex value when I break on the init_my_type
:
(gdb) finish
Value returned is $26 (void *) 0x79b6c0
Later, inside the do_stuff
function, my_ptr
has the same hex value:
(gdb) print my_ptr
$26 = (my_type *) 0x79b6c0
but, when I break on func
the argument it gets has a totally different value.
Breakpoint 2, func(arg=0x1388)
I am type-punning pointers all over the place, but I don't see that that should change the address in memory that they point to, right? Also, the function func
is declared inline
but why should that affect this? This all seems correct to me -- it is entirely possible that I'm doing something stupid that I don't see.
Here is a complete program of the simplified code. In reality, all these functions don't get called by main, but by dynamically loaded helper functions. Still, I don't see how the address pointed to by my_ptr
should change when passed to func
.
#include "stdlib.h"
#include "stdio.h"
typedef struct _type{
int *i1;
float *f1;
}my_type;
static my_type *my_ptr;
void *init_my_type(void){
my_type *x = malloc(sizeof(my_type));
x->f1 = malloc(sizeof(float));
x->i1 = malloc(sizeof(int));
x->f1[0] = 123.456;
x->i1[0] = 789;
return x;
}
void init(void){
my_ptr = init_my_type();
}
inline void func(void *arg){
my_type *x = (my_type *)arg;
printf("%d %f\n", *x->i1, *x->f1);
}
void do_stuff(void){
func(my_ptr);
}
int main(void){
init();
do_stuff();
}
回答1:
The following is not the cause of the issue (and can't, since static globals are initialised to zero by default). Though the basic idea is still relevant: whether the passed pointer is really the same that got initialised.
A wild guess:
static my_type *my_ptr;
Could it be that this line is part of some header file? Because then you have a global my_ptr
in every source file that includes this header.
Since you wrote that this is a very large project, I assume that you separated the code and put it into multiple source files. Assuming the init function is in a different source file than the using function, then this would mean they're accessing different pointers. While the one init
deals with gets initialised, the one func
is using is uninitialised.
To check this you should print the address of the global pointer variable (&my_ptr
) in both functions.
来源:https://stackoverflow.com/questions/31883366/incorrect-pointer-value-passed-to-a-c-function