2

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

#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);

它运行无效的免费(奇怪,因为如果 Raiz 为 NULL,则免费不应该运行。有人可以帮我解决这个问题吗?我认为这个警告也是让我无法“释放”的问题。

编辑:好的关于waring的问题已解决。但是,如果我免费执行 2 次,它会运行无效的免费(我有一个可以免费执行某些操作的函数,其他时候没有。如果我执行免费,“if(Raiz!=NULL)”应该阻止另一个免费运行。但它不是。

4

4 回答 4

7

一个问题是调用malloc()以及您没有通过 include 声明的malloc()事实<stdlib.h>

默认情况下,假定函数返回intC99 之前的代码 - 在 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 在处理 s 的重新定义方面比 C99 或 C89 具有更大的灵活性typedef)。函数名之前的使用extern不是绝对必要的,尽管我更喜欢看到它——如果只是为了与extern在标头中声明的任何变量之前必须存在的对称(如果有的话——全局变量应该避免)可能的)。

然后实现文件tipopagina.c可能会启动:

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

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

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

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

于 2013-04-14T04:11:24.180 回答
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.

于 2013-04-14T03:32:47.167 回答
0

好的....我认为不能这样做:

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

无论如何,这将变得无效。剩下的问题通过那里的一些答案解决了。我已经接受了最完整的。但是感谢大家的帮助!

于 2013-04-18T20:28:28.410 回答
0

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

  1. 包含与您粘贴的头文件不同的头文件(如果它们位于 .h 文件中)
  2. 包括另一个头文件,该文件也定义了具有该名称的类型或函数,尽管在这种情况下我会收到警告
  3. TipoApontadoreNovaSubArvore实际上未在 中声明main,并且编译器正在分配默认类型。(这对我来说似乎是最有可能的。如果是这种情况,您应该会收到这样的警告。)

当然,这不是一个详尽的清单,但这些事情以前发生在我身上。

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

于 2013-04-14T03:30:15.857 回答