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

Bre*_*tos 2 c struct pointers

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

#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);
}
Run Code Online (Sandbox Code Playgroud)

在主要我打电话:

TipoApontador Raiz;
Run Code Online (Sandbox Code Playgroud)

然后:

Raiz=NovaSubArvore(ordem); //Warning happens here
Run Code Online (Sandbox Code Playgroud)

如果我做:

if (Raiz!=NULL)
    free(Raiz);
Run Code Online (Sandbox Code Playgroud)

它运行一个免费的invallid(奇怪,因为如果Raiz是NULL,免费应该没有运行.请问有人帮我解决这个问题吗?我认为这个警告是让我免于"解放"的问题.

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

Jon*_*ler 7

一个问题是调用malloc()和你没有malloc()通过包含声明的事实<stdlib.h>.

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

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

gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition ...
Run Code Online (Sandbox Code Playgroud)

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


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

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

TipoApontador NovaSubArvore(int ordem) { ... }
Run Code Online (Sandbox Code Playgroud)

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

TipoApontador Raiz;

...

Raiz = NovaSubArvore(ordem); //Warning happens here
Run Code Online (Sandbox Code Playgroud)

类型名称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 */
Run Code Online (Sandbox Code Playgroud)

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

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

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

TipoApontador NovaSubArvore(int ordem)
{
    TipoApontador A = malloc(sizeof(TipoPagina));
    ...
    return (A);
}
Run Code Online (Sandbox Code Playgroud)

将标题放在第一位是有充分理由tipopagina.h; 它确保标头可以单独使用(这很重要).

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