警告:赋值使用整数而不使用强制转换

时间:2013-04-14 03:25:21

标签: c pointers struct

我正在从指针进行强制转换然后它让我继续运行此警告(赋值使得整数指针没有强制转换)。 这是代码:

#include<stdio.h>
#include<stdbool.h>



typedef int TipoChave;

typedef struct TipoRegistro {
  TipoChave Chave;
  /*outros componentes*/
} TipoRegistro;

typedef struct TipoPagina* TipoApontador;

typedef struct TipoPagina {
  int registros;
  TipoRegistro *r;
  TipoApontador *p;
} TipoPagina;

TipoApontador NovaSubArvore(int ordem){
    TipoApontador A;
    A=malloc(sizeof(TipoPagina));
    int i;
    A->registros=0;
    A->r=malloc((2*ordem)*sizeof(TipoRegistro));
    A->p=malloc((2*ordem+1)*sizeof(TipoPagina));
    for (i=0;i<(2*ordem+1);i++){
        A->p[i]=NULL;
        if(i!=2*ordem){
            A->r[i].Chave=0;
        }
    }
    return (A);
}
主打电话

TipoApontador Raiz;

然后:

Raiz=NovaSubArvore(ordem); //Warning happens here

如果我这样做:

if (Raiz!=NULL)
    free(Raiz);

它运行一个invallid free(奇怪,因为如果Raiz是NULL,则free应该没有运行。 有人可以帮我解决这个问题吗?我认为这个警告是让我免于“解放”的问题。

编辑:好的问题解决了。但是如果我做了2次免费游戏就会运行一个无效的免费游戏(我有一个免费的东西,其他时间没有。如果我自由地执行“if(Raiz!= NULL)”应该阻止另一个免费的跑步。但事实并非如此。

4 个答案:

答案 0 :(得分:7)

一个问题是对malloc()的调用以及您未通过加入malloc()来声明<stdlib.h>这一事实。

默认情况下,假定函数在C99之前的代码中返回int - 在C99代码中,您应该在使用它之前声明一个函数。

您需要使用更多警告选项进行编译。如果您使用GCC,我建议:

gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition ...

这几乎可以确保您没有使用未申报的功能(例如malloc())。根据您使用的GCC版本,默认情况下可能会启用或多或少的警告。一般来说,较新的版本比较简单,但不是那么简单。


另一个问题似乎是您有一个源文件(问题中没有给出名称),其中包含类型定义和函数定义,例如:

typedef struct TipoPagina* TipoApontador;
typedef struct TipoPagina { ... } TipoPagina;

TipoApontador NovaSubArvore(int ordem) { ... }

在此文件中,类型是已知的。在主代码中,您有:

TipoApontador Raiz;

...

Raiz = NovaSubArvore(ordem); //Warning happens here

此文件中必须知道类型名称TipoApontador,但您的代码似乎不包含NovaSubArvore()的声明。

对于将在多个源文件中使用的类型和函数,应该有一个标题定义类型并声明函数。标题应该在定义函数的源文件和使用类型和函数的源文件中使用。

例如,标题可能是tipopagina.h

#ifndef TIPOPAGINA_H_INCLUDED
#define TIPOPAGINA_H_INCLUDED

typedef int TipoChave;

typedef struct TipoRegistro {
  TipoChave Chave;
  /*outros componentes*/
} TipoRegistro;

typedef struct TipoPagina* TipoApontador;

typedef struct TipoPagina {
  int registros;
  TipoRegistro *r;
  TipoApontador *p;
} TipoPagina;

extern TipoApontador NovaSubArvore(int ordem);

#endif /* TIPOPAGINA_H_INCLUDED */

头部防护很重要;它们避免了重新定义类型的问题(尽管C11在处理typedef s的重新定义时比C99或C89具有更大的灵活性)。在函数名之前使用extern并不是绝对必要的,尽管我更愿意看到它 - 如果只是为了与extern对称,那么在标题中声明的任何变量之前必须存在该对称性(如果有任何 - 应尽可能避免全局变量。)

然后实施文件tipopagina.c可能会开始:

#include "tipopagina.h"
#include <stdlib.h>

TipoApontador NovaSubArvore(int ordem)
{
    TipoApontador A = malloc(sizeof(TipoPagina));
    ...
    return (A);
}

首先放置tipopagina.h标头good reason;它确保标题可以单独使用(这很重要)。

主代码还包括tipopagina.h,并且因为函数NovaSubArvore()在标头中声明,所以可以避免编译器警告。

答案 1 :(得分:1)

代码看起来没问题,但如果我在定义main之前放NovaSubArvore,那么我会看到完全相同的错误:

int main()
{
   TipoApontador Raiz;
   int ordem = 10 ;
   Raiz=NovaSubArvore(ordem); 
}

TipoApontador NovaSubArvore(int ordem){
 /// Rest of the function
}

所以在这种情况下,返回类型将默认为int。在K&R C中,如果您将其保留为默认为int的类型。

答案 2 :(得分:0)

对我来说这看起来不错。您确定TipoApontadorNovaSubArvore的给定定义是main中引用的定义吗?您可能没有使用这些定义的方法是(例如):

  1. 包含与您粘贴的头文件不同的头文件(如果这些文件位于.h文件中)
  2. 包含另一个头文件,该文件也定义了具有该名称的类型或函数,但在这种情况下我希望发出警告
  3. TipoApontadoreNovaSubArvore实际上未在main中声明,并且编译器正在分配默认类型。 (这似乎对我来说最有可能。如果是这种情况,你应该期待这种效果的警告。)
  4. 当然,这不是一个详尽的清单,但这些事情在我之前发生过。

    编辑:此外,您是否打开了编译器发出的所有警告?例如,如果您使用的是gcc,是否使用了-Wall选项?

答案 3 :(得分:0)

好吧....我认为不可能做到这样:

free (Raiz)
if (Raiz!=NULL)
    free(Raiz);

无论如何,这将无效。 其余的问题是由那里的一些答案解决的。我接受了最完整的。但是,感谢大家的帮助!