【问题标题】:retrieve pointers in a function检索函数中的指针
【发布时间】:2018-02-18 12:50:27
【问题描述】:

我想在一个函数中接收用数据(包括指针)填充一个结构,我将要填充的结构的指针传递给该函数。现在我意识到我在退出函数时丢失了指针,因此我相信我可能需要使用双指针。那是对的吗?我想出了一个示例程序,它可以编译但由于访问main() 中的无效指针而遇到段错误(第 43 行),请参见下文:

#include <stdio.h>

#define NUM 100

typedef enum state_e {
        SM_ANALYZE = 0,           
        SM_TX,                    
        SM_PEND,                  
} state_t;

typedef struct data_s {
        int flags;             
        int id;                
        int local_min_tx;      
        int local_min_rx;      
        int local_detect_mult; 
        int egr_obj;           
        int label;             
        int egress_label;      
        int port;              
        state_t state;
}data_t; 

typedef struct content_s{
        state_t state;
        data_t *pData;
        void (*cbck)(data_t*,state_t);
}content_t;

static content_t MyCont[NUM]={0};
static data_t MyDat[NUM]={0};

void callback(data_t *pDat,state_t state);

int main(void)
{
content_t locC = {0};
callback_reg(1,callback);
data_set(1,&MyCont[1],SM_PEND);
data_get(1,&locC);


printf("cbck %p\ndata %p\nstate %d\nlabel %d",locC.cbck,
                                              locC.pData,
                                              locC.state,
                                              locC.pData->label);

MyCont[1].cbck(&MyDat[1],MyDat[1].state);
}

void callback(data_t *pDat,state_t state)
{
        printf("in user callback!\n");
        printf("BFDId %d is now %d\n",pDat->id,state);
        return;
}
int data_set(int id, content_t *pDat, state_t state)                
{                                                                           
        pDat->pData = &MyDat[id];
        pDat->state = state;
}                                                                           

int callback_reg(int id, void (*cb)(data_t*,state_t))        
{                                                                           
    MyCont[id].cbck=cb;
}                                                                           
int data_get(int id, content_t *pDat)
{
    pDat = &MyCont[id];
}
//--------------------------------------------------------------------------

【问题讨论】:

  • 你能指出导致问题的行吗? 43号线一一数出来,很繁琐。
  • 你的 data_get 函数说它会返回一个 int,但它没有,data_set 和 callback_reg 是相同的,未定义的行为 #1。为什么不直接返回指针呢?
  • @ZamronyP.Juhara 当然,对不起!是main() 中的printf90 导致了问题
  • 发布的代码可能会在您的 printf 之前破坏堆栈 3 次,这会从堆栈中提取它的参数。您看到第一种未定义行为是如何使您的程序无效的吗?是的,您在分配指针时也有问题,但在您解决其他问题之前,这不是您唯一的问题。也许您还应该使用 -Wall 进行编译。
  • 旁注:如果您在 POSIX 系统上,带有_t 后缀的名称将保留用于实现。

标签: c pointers struct variable-assignment dereference


【解决方案1】:

这里

int data_get(int id, content_t *pDat)
{
  pDat = &MyCont[id];
}

local 变量 pDat 被赋值,然后函数离开,pDat 被释放为本地变量。

你想要的是:

#include <errno.h> /* for errno */

/*
 * Gets content_t from MyConf at index id.
 *
 * Returns 0 on success or -1 on error.
 */
int data_get(size_t id, content_t *pDat)
{
  int result = 0;

  if (NULL == pDat)
  {
    errno = EINVAL;
    result = -1;
  }
  else if (NUM <= id) 
  {
    errno = ERANGE;
    result = -1;
  }
  else
  {
    *pDat = MyCont[id]; /* Copy MyCont[id] to where pDat points. */
  }

  return result;
}

然后这样称呼它:

#include <stdlib.h> /* for EXIT_FAILURE */
#include <stdio.h> /* for perror() */

int data_get(int, content_t *);

int main(void) 
{
  ..
  if (-1 == data_get(1,&locC))
  {
    perror("data_get(1, ...) failed");
    exit(EXIT_FAILUE);:
  }

【讨论】:

  • 我一直认为(精神缺陷)if (data_get(1,&amp;locC) = -1) 在我的眼睛里流淌得更好——虽然理解它不会产生“豆子山”的不同。我猜是 6 比 1、1/2 打到另一个……
  • 这当然表明“原力与你同在”...我想我只是需要更多的绝地训练...
猜你喜欢
  • 1970-01-01
  • 2022-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多