2013-04-14 1 views
2

포인터에서 캐스트를 수행하면이 경고가 계속 실행됩니다 (할당은 캐스트없이 정수에서 포인터를 만듭니다). 내가 할 경우경고 : 캐스팅없이 정수에서 포인터를 할당합니다.

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

:

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

주요 I의 통화 : 다음

TipoApontador Raiz; 

여기에 코드입니다

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

그것이 invallid 무료 실행 (이상한데 왜냐하면 Raiz가 NULL이기 때문입니다. 자유가 없어야했습니다. 아무도 저 문제를 도와 줄 수 있습니까? 나는이 경고가 나를 "자유롭게"하지 못하게하는 문제라고 생각한다.

편집 : 문제 해결에 관한 OK 문제. 그러나 내가 2 번 무료로한다면 그것은 무효 무료 (나는 무료 somethings, 다른 시간 않는 기능이 있습니다. 내가 무료로 할 경우 "(Raiz! = NULL)"다른 무료 차단해야합니다. ...?들이받은하지만 그렇지 않은 나에게 확인을 보이는

+1

'메인'파일이 같은 파일에 있는지, 다른 파일에 있습니까? 동일한 파일에 있다면'main'이'NovaSubArvore' 앞이나 뒤에 정의되어 있습니까? – dasblinkenlight

+0

Nope. struct 및 함수 범위와 ".c"및 함수 선언에 대한 헤더가 있습니다. 먼저 "main.c"(주 기능 이전)에 헤더를 포함합니다.헤더에 나는 아무것도 포함하지 않고 ".c"에 헤더를 포함합니다. –

+0

종류와 크기를 확인하십시오! 또한 A-> p = malloc ((2 * ordem + 1) * sizeof (A * -p))을 A-> p = malloc ((2 * ordem + 1) * sizeof (TipoPagina) > p);'(그리고 typedef 뒤에 포인터를 숨기지 마십시오. 사람들을 혼란스럽게합니다.) – wildplasser

답변

7

malloc()으로 전화하는 중 하나는 <stdlib.h>을 포함하여 malloc()을 신고하지 않았다는 것입니다.

기본적으로 함수는 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을 다시 정의 할 때 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

선언 한 모든 함수는 다음 경고와 함께 나타납니다. "function"에 대한 이전 프로토 타입이 없습니다. 나는 이것이 무엇을 의미하는지 모른다. –

+0

이것은 두 가지 방법 중 하나로 문제를 해결할 수 있음을 의미합니다. 하나는'static' 함수를 만드는 것인데, 그것의 정의도 선언이다; 이 기능이 다른 소스 파일에서 사용되지 않은 경우에 적합합니다. 다른 하나는 헤더에 형식적 선언을 제공하여 함수가 다른 파일에서 사용하도록 적절히 선언되도록하는 것입니다. –

0

을 당신에게 TipoApontadorNovaSubArvore의 주어진 정의는 main에서 참조되는 것들입니다 확실 당신이 그되어 정의를 사용하지 않을 수 있습니다 방법 (예를 들어)입니다 : 또한 종류 나 쿵푸를 정의하는 또 다른 헤더 파일을 포함 (사람들이 .H 파일에 거주하는 경우)에서 붙여 넣기 한 하나

  • 는 다른 헤더 파일을 포함

    1. 이 경우에 경고가 나올 것으로 예상되지만,
    2. TipoApontadore 또는 NovaSubArvore은 실제로는 main으로 신고되지 않으며 컴파일러는 기본 유형을 지정합니다. 이 경우 가장 가능성이 높습니다.이 경우 경고 메시지가 나타납니다.

    물론이 목록은 완전한 목록은 아니지만 이전에 이러한 일이 발생했습니다.

    EDIT : 또한 컴파일러의 모든 경고를 켜시겠습니까? 예를 들어 gcc를 사용하는 경우 -Wall 옵션을 사용하고 있습니까?

  • +0

    벽을 사용하면 다음과 같이 나타납니다 : 함수의 암시 적 선언 NovaSubArvore. –

    +0

    작동하지만, if (Raiz! = NULL) 무료 (Raiz); 은 여전히 ​​유효하지 않은 무료 문자를 반환합니다. –

    +0

    그 경고는 당신이 그것을 선언하지 않고'NovaSubArvore'를 사용하고 있다는 것을 의미합니다. 이 경우 컴파일러는 @ShafikYaghmour가 위에서 지적한대로'NovaSubArvore'의 반환 유형이'int'라고 가정합니다. 'maino'를 포함하고있는 .c 파일의 .h 파일에'maina '의 어딘가에'TipoApontador NovaSubArvore (int ordem);과 같은 문장을 넣어서 사용하기 전에 *'NovaSubArvore'를 선언해야합니다. 'main' 위의 .c 파일에 직접 붙여 넣기 만하면됩니다. (.h 접근법은 스타일이 잘 어울립니다.) – sigpwned

    1

    코드는 괜찮아 보이지만 그때 정의 NovaSubArvore 이전 main을 세우면 나는 똑같은 오류를 참조하십시오

    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로 설정해야합니다. –

    관련 문제