2013-04-14 54 views
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); 

它运行invallid免费(奇怪,因为如果Raiz是NULL免费不应该跑。 任何人都可以帮我解决这个问题吗?我认为这个警告是让我免于“释放”的问题。

编辑:关于华林解决好问题。但如果我免费2次运行一个无效的免费(我有一个功能,做一个免费的东西,其他时间不是。如果我做免费的“if(Raiz!= NULL)”应该阻止其他免费。?乳宁,但它不是

+1

是你的'主'在同一个文件中,还是在不同的?如果它在同一个文件中,在'NovaSubArvore'之前或之后是否定义了'main'? – dasblinkenlight

+0

没有。我有一个头结构和函数作用域和一个“.c”和函数声明。首先我在“main.c”(main函数之前)包含头文件。在标题上我什么都没有,并在“.c”中包含标题。 –

+0

检查类型和尺寸!这也是将A-> p = malloc((2 * ordem + 1)* sizeof(TipoPagina));'into'A-> p = malloc((2 * ordem + 1)* sizeof * A- > p(并且请不要在typedefs后面隐藏指针,它只会让人困惑) – wildplasser

回答

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(),所以避免了编译器警告。

+0

我声明的每个函数都会显示警告: 没有以前的“函数”原型。我不知道这是什么意思。 –

+0

这意味着你有两种方法来解决这个问题。一个是使功能“静态”,所以它的定义也是它的声明;如果该函数没有用于任何其他源文件,这是适当的。另一种是在头文件中提供一个正式的声明,以便该函数适当地声明用于其他文件。 –

0

这看起来确定我是否确定的TipoApontadorNovaSubArvore给出的定义是main所引用的那些你可能不使用这些defintions被方式是(例如):

  1. 包括比你从粘贴(如果这些生活在.h文件)的一个
  2. 包括另一头文件还定义了一个类型或福不同的头文件虽然我希望在这种情况下发出警告
  3. TipoApontadoreNovaSubArvore实际上在main中未声明,编译器正在分配默认类型。 (这似乎是我最可能的情况,如果是这种情况,你应该期待这个效果的警告。)

当然,这不是一个详尽的列表,但那些事情发生在我之前。

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

+0

如果我使用wall,它会出现: 函数NovaSubArvore的隐式声明也一样。 –

+0

它的工作原理,但 如果(Raiz!= NULL) 免费(Raiz); 仍然返回无效的免费。 –

+0

该警告意味着您正在使用'NovaSubArvore'而不声明它。在这种情况下,编译器假定'NovaSubArvore'的返回类型是'int',就像@ShafikYaghmour指出的那样。你需要在声明''NovaSubArvore''之前声明'TipoApontador NovaSubArvore(int ordem);'在'main'之前的某处,在.h文件中包含'main'的.c文件包含或只是直接粘贴在'main'上面的.c文件中。 (.h方法肯定更好,风格上。) – sigpwned

1

代码看起来不错,但如果我把mainNovaSubArvore之前定义,那么我看到确切的同样的错误:

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

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

所以在这种情况下,返回类型将默认为int。在K&R C如果您忽略该类型,它将默认为int

0

确定....我认为它不能做这样的事情:

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

这将让无效免费反正。 问题的其余部分通过一些答案解决。我接受了最完整的。但是,感谢所有人试图帮助!

+0

仅仅因为你释放了指针,指针没有设置为NULL。释放后,您需要将其设置为NULL。 –

相关问题