【问题标题】:Returning a pointer to an array of pointers to structs返回指向结构指针数组的指针
【发布时间】:2011-02-03 14:51:28
【问题描述】:

所以,我遇到了一个小问题。我正在尝试构建一个哈希表,但我不断收到一条错误消息,提示“从不兼容的指针类型返回”。我知道这意味着什么,但我不知道为什么我的代码不起作用。我正在寻找为什么我的代码不起作用的解释。为什么不将数组识别为指针?

我正在为哈希表创建一个指向结构的指针数组。 (外链) (我知道我的代码可能真的很烂>

struct hashTBL {

    char *userID;
    char *password;
    struct hashTBL *next;
};

typedef struct hashTBL Tbl;
typedef struct hashTBL* TblPTR;

TblPTR createHashTBL(int size)
{
    char *userID;
    char *password;
    int i;

    TblPTR hashArray[size];

    FILE* fpData;
    char *fileName = "encrypted.txt";

    fpData = openReadFile(fileName);

    TblPTR T = NULL;

    while((fscanf(fpData, "%s", userID)) != EOF)
    {
        fscanf(fpData, "%s", password);
        i = hash(userID, size); 



        if(hashArray[i] != NULL) 
        {
            TblPTR H = hashArray[i];

            while(H != NULL)
            {
                T = H;
                H = H->next;
            }
            H = newPTR(userID, password, T);
        }
        else
        {
            hashArray[i] = newPTR(userID, password, T);
        }

    }
    closeFile(fpData);
    return &hashArray;  
}



TblPTR newPTR(char *userID, char *password, TblPTR T)
{

    TblPTR H = (TblPTR)malloc(sizeof(Tbl));
    if(T != NULL) T->next = H;
    H->userID = userID;
    H->password = password;
    H->next = NULL;

    return H;
}

【问题讨论】:

  • 快速浏览后,代码似乎有效,尽管即使编译器确实告诉你它在哪一行,也很难发现代码中的错误。它在哪一行失败?
  • 请提供尽可能接近可编译的代码示例,或指出错误发生的位置。我假设TblPTRTbl* 的typedef,但您没有提供Tbl 的定义。
  • return statment "从不兼容的指针类型返回" "函数返回局部变量的地址"

标签: c pointers data-structures


【解决方案1】:

你至少有两个问题。

首先,您的createHashTBL() 函数被定义为返回一个TblPTR 对象,并且您正在返回一个指向TblPTR 对象数组的指针。您应该更改函数类型以匹配您尝试的返回类型,或者返回正确的对象类型。

其次,您的hashArray 是在createHashTBL() 函数中堆栈分配的,这意味着您不能返回指向它的指针。当你的函数返回时它会消失。您应该尝试使用 malloc() 分配数组或让调用者提供指向预分配数组的指针。

【讨论】:

  • 您的意思一定是:hashArraycreateHashTBL堆栈分配
  • 啊! :) 返回指针的类型究竟是什么?因为我真的不确定你会怎么做。
  • 假设您解决了内存分配问题,您可以只将 TblPTR 对象返回到数组中的第一个元素,如下所示:return hashArray
【解决方案2】:

TblPTR hashArray[size]; 在堆栈上创建,无法返回,因为您的变量将在函数结束时销毁。

您应该改用 malloc() 或 static TblPTR hashArray[size];(不推荐)。

这是错误的:

    return &hashArray;

您正在返回一个指向您的数组的指针:(TblPTR*)。做吧

    return hashArray;

【讨论】:

    【解决方案3】:

    您的编译器错误提示它也可能是另一个问题,例如缺少 typedef。您应该始终复制/粘贴错误消息,以便我们检查它们,并在您粘贴的代码中指出错误在哪一行 - 这将有助于每个人理解问题

    这里有一些错误。

    TblPTR createHashTBL(int size) {
    
     ... 
     TblPTR hashArray[size];
     ..
    
     return &hashArray;
    }
    
    • 您不能返回指向局部变量的指针 - 当函数返回时该变量消失了
    • createHashTable 被声明为返回 TblPTR,但返回 &hashArray;有一个完全不同的类型,它是一个指向 TblPTR 数组的指针。

    那个函数应该是

    TblPTR *createHashTBL(int size) {
    
     ... 
     TblPTR *hashArray = malloc(size * sizeof *hashArray);
     ..
    
     return hashArray;
    }
    

    (记得释放()元素和 hashArray 当你完成它)

    【讨论】:

      【解决方案4】:

      你有两个主要问题:

      1. 表达式&hashArray的类型是TblPTR (*)[size](指向size的指针-TblPTR的元素数组),而不是TblPTR;这就是您的类型不匹配警告的来源。不过……

      2. hashArray 是函数本地的;一旦函数退出,hashArray 就不再有效,所以你将返回一个指向垃圾的指针。

      VLA 不是在这里使用的正确工具。我建议进行以下更改:

      TblPTR *createHashArray(size)       // return a pointer to TblPTR
      {
        ...
        TblPTR *hashArray = malloc(sizeof *hashArray * size);
        if (hashArray)
        {
          // initialize hash array as you're currently doing
        }
        return hashArray;
      }
      

      请注意,您必须在稍后的代码中 free() 数组。

      【讨论】:

        猜你喜欢
        • 2014-12-30
        • 1970-01-01
        • 1970-01-01
        • 2017-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-21
        相关资源
        最近更新 更多