简体   繁体   English

传递给C函数的指针值不正确

[英]incorrect pointer value passed to a C function

I have a bug in which an incorrect value gets passed as an argument to a function in a C program. 我有一个错误,其中错误的值作为参数传递给C程序中的函数。 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: 函数init_my_type非常简单:

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: 稍后,我将my_ptr用作另一个函数的参数:

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. 我遇到的问题是,当访问my_ptr指向的数据结构中的某些数据时,我会在func造成my_ptr

When I run the debugger I get a nice looking hex value when I break on the init_my_type : 当我运行调试器时,在中断init_my_type时会得到一个漂亮的十六进制值:

(gdb) finish
Value returned is $26 (void *) 0x79b6c0

Later, inside the do_stuff function, my_ptr has the same hex value: 稍后,在do_stuff函数中, my_ptr具有相同的十六进制值:

(gdb) print my_ptr
$26 = (my_type *) 0x79b6c0

but, when I break on func the argument it gets has a totally different value. 但是,当我中断func ,它得到的参数具有完全不同的值。

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? 另外,函数func被声明为inline函数,但是为什么要影响它呢? 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. 实际上,所有这些函数都不会由main调用,而是由动态加载的辅助函数调用。 Still, I don't see how the address pointed to by my_ptr should change when passed to func . 不过,我看不到my_ptr指向的地址传递给func my_ptr如何更改。

#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();


}

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. 因为这样,每个包含此头的源文件中都有一个全局my_ptr

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. 假设init函数与using函数位于不同的源文件中,则意味着它们正在访问不同的指针。 While the one init deals with gets initialised, the one func is using is uninitialised. 当一个init处理被初始化时,一个正在使用的func未初始化。

To check this you should print the address of the global pointer variable ( &my_ptr ) in both functions. 要检查这一点,您应该在两个函数中都打印全局指针变量( &my_ptr )的地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM