【问题标题】:Compiler warnings and notes but dropping & does not work编译器警告和注释但删除 & 不起作用
【发布时间】:2016-04-08 12:45:05
【问题描述】:

在下面的代码 sn-p 中,我收到 gcc 编译器警告:“从不兼容的指针类型 initArr(&stack,2); 传递 initArr 的参数 1;” 和注释:“预期为 'struct Arr *' 但参数的类型为 'struct Arr**'” 这对我来说很有意义。

正如许多 SO 帖子所建议的那样,从对 initArr(&stack, 2) 的调用中删除 & 符号会导致另一个警告:“'stack' is used unitialized in this function: init(stack, 2);”运行时立即出现段错误。

我做错了什么?

我还尝试在 malloc sizeof 调用中使用 struct Arr,并且正如预期的那样,没有变化。

#include<stdio.h>
#include <stdlib.h>
#define TYPE int

struct Arr {
    TYPE * data;    // Pointer to the data array.
    int size;       // Number of elements in the array.
    int capacity;   // Capacity of the array.
};

void initArr(struct Arr * da, int capacity) {
    da->data = malloc(sizeof(TYPE) * capacity);
    da->size = 0;
    da->capacity = capacity;
}

int main() {
    struct Arr *stack;
    initArr(&stack, 2);

    return 0;
}

【问题讨论】:

  • @chux 谢谢你,我会努力合并你的格式。

标签: c


【解决方案1】:

正如黑客的回答所说,

  • 你需要初始化你的指针,让它指向一个真实的位置
  • 传递指针(而不是指针变量的地址)

    int main() 
    {
       struct Arr realArray;   // allocate memory for the Arr (on the CPU's stack)
       struct Arr *stack;      // pointer variable (undefined)
    
       stack = &realArray;     // make variable "stack" point to realArray
    
       initArr(stack, 2);      // pass the pointer to realArray
    } 
    

【讨论】:

  • 这三个答案都是正确的。谢谢大佬!!
【解决方案2】:

stack 是一个指针,它必须指向某个有效的内存位置。由于stack 已传递给函数并且未初始化,因此您会收到警告。在函数中,您试图访问一些随机内存位置,这可能导致程序崩溃或程序的任何错误行为,即未定义的行为。

【讨论】:

    【解决方案3】:

    改变这个:

    struct Arr *stack;
    

    到这里:

    struct Arr stack;
    

    【讨论】:

      【解决方案4】:

      先看看你的initArr函数的声明:

      void initArr(struct Arr * da, int capacity)
      

      您的第一个参数的类型是“指向结构的指针”

      现在看看你对这个函数的调用:

      struct Arr *stack;
      initArr(&stack, 2);
      

      我们看到堆栈的类型是“指向结构的指针”,并且在函数中传递堆栈的地址(.i.e. 类型是指向结构指针的指针) .这就是 gcc 错误的含义,该注释实际上提供了有关函数期望的类型和您提供的类型的更多信息

      有两种方法可以解决这个问题

      1. 保持initArr的声明不变,然后改变函数 从initArr(&amp;stack, 2) 调用到initArr(stack, 2)。在这种情况下,您需要确保在将结构传递给函数之前已为结构分配了内存;

         int main()
         {
             struct Arr* da = NULL;
             da = malloc(sizeof(struct Arr));
        
             initArr(da, 2);
         }
        

      或等价的,

           int main
           {
               struct Arr     stack;
      
               initArr(&stack, 2);
           }
      

      我可能会选择上述解决方案之一。

      1. 修改initArr的声明为initArray(struct Arr** da, int capacity)。您仍然需要确保像以前一样分配内存。但是,如果您将 initArr 更改为:

        void initArr(struct Arr** da, int capacity)
        {
             *da = malloc(sizeof(struct Arr));
             (*da)->data = malloc(sizeof(TYPE) * capacity);
             (*da)->size = 0;
             (*da)->capacity = capacity;
        }
        

      在这种情况下,我将更改您的 initArr 函数的语义,以便将结构全部初始化在一个地方。 main 函数中的代码将保持不变。

      注意为清楚起见,上述代码 sn-ps 中省略了错误检查,请不要在实际代码中这样做。始终检查 malloc 的返回值以确保已分配内存。

      【讨论】:

        猜你喜欢
        • 2015-09-20
        • 2014-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-23
        • 2014-08-14
        • 1970-01-01
        • 2016-03-27
        相关资源
        最近更新 更多