incorrect pointer value passed to a C function

老子叫甜甜 提交于 2020-01-17 12:23:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!