2013-04-14 59 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。 –

相關問題