2

I'm doing cast from a pointer then it keeps me runing this warning (assignment makes pointer from integer without a cast). here's the code:

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

on main I call:

TipoApontador Raiz;

then:

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

if I do:

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

it runs a invallid free (strange, because if Raiz is NULL the free shouldn't had run. Can anyone help me with that problem, please? I think that this warning is the problem that keeps me from "freeing" too.

EDIT: OK problem about waring solved. But if I do the free 2 times it runs a invalid free (I have a function that does a free somethings, other-times not. If I do the free the "if(Raiz!=NULL)" should block the other free from runing. but it isn't.

Breno Santos
  • 174
  • 1
  • 3
  • 12
  • 1
    Is your `main` in the same file, or in a different one? If it is in the same file, is `main` defined before or after `NovaSubArvore`? – Sergey Kalinichenko Apr 14 '13 at 03:29
  • Nope. I have a header for the struct and functions scope and a" .c" and the function declaration. first I include the header on "main.c" (before main function). On the header I include nothing and on the ".c" I include the header. – Breno Santos Apr 14 '13 at 03:59
  • Check the types and sizes! Also a good reason to change `A->p=malloc((2*ordem+1)*sizeof(TipoPagina));` into `A->p=malloc((2*ordem+1)*sizeof *A->p);` (and please don't hide pointers behind typedefs. It only confuses people) – wildplasser Apr 14 '13 at 16:33

4 Answers4

7

One problem is the calls to malloc() and the fact that you've not declared malloc() by including <stdlib.h>.

By default, functions are assumed to return an int in pre-C99 code — in C99 code, you're supposed to declare a function before using it.

You need to compile with more warning options. If you use GCC, I recommend:

gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition ...

This pretty much ensures that you don't have undeclared functions (such as malloc()) used. Depending on the version of GCC you use, you may get more or less warnings enabled by default. In general, newer versions are fussier, though it isn't quite that simple.


The other problem appears to be that you have a source file (name not given in the question) containing type definitions and function definitions such as:

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

TipoApontador NovaSubArvore(int ordem) { ... }

Within this file the types are known. In your main code, you have:

TipoApontador Raiz;

...

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

The type name TipoApontador must be known in this file, but it appears that your code does not include a declaration for NovaSubArvore().

For types and functions that are going to be used in multiple source files, there should be a header defining the types and declaring the functions. The header should be used in both the source file that defines the functions and in the source files that use the types and functions.

For example, the header might be 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 */

The header guards are important; they avoid problems with redefining types (though C11 has more flexibility than either C99 or C89 in handling redefinitions of typedefs). The use of extern before the function name is not strictly necessary, though I prefer to see it — if only for symmetry with the extern that must be present before any variables that are declared in the header (if there are any — global variables should be avoided whenever possible).

Then the implementation file tipopagina.c might start:

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

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

There's a good reason for putting the tipopagina.h header first; it ensures that the header can be used on its own (which is important).

The main code also includes tipopagina.h, and because the function NovaSubArvore() is declared in the header, you avoid the compiler warning.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Every function that I've declared appears with the warning: No previous prototype for "function". I don't know what this means. – Breno Santos Apr 14 '13 at 04:22
  • It means you have one of two ways to fix the issue. One is to make the function `static`, so its definition is also its declaration; this is appropriate if the function is not used in any other source file. The other is to provide a formal declaration, in a header, so that the function is properly declared for use in other files. – Jonathan Leffler Apr 14 '13 at 04:27
1

The code looks okay but if I put main before NovaSubArvore is defined then I see the exact same error:

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

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

so in this case the return type will default to int. In K&R C i f you leave off the type it will default to int.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
0

That looks OK to me. Are you sure the given definitions of TipoApontador and NovaSubArvore are the ones being referenced in main? Ways you might not be using those defintions are (for example):

  1. Including a different header file than the one you've pasted from (if those live in a .h file)
  2. Including another header file that also defines a type or function with that name, although I would expect a warning in this case
  3. TipoApontadore or NovaSubArvore are actually undeclared in main, and the compiler is assigning default types. (This seems the most likely to me. If this is the case, you should expect a warning to this effect.)

Of course, this is not an exhaustive list, but those things have happened to me before.

EDIT: Also, are you turning on all warnings from the compiler? For example, if you're using gcc, are you using the -Wall option?

sigpwned
  • 6,957
  • 5
  • 28
  • 48
  • If I use wall it appears: Implicit declaration of function NovaSubArvore too. – Breno Santos Apr 14 '13 at 04:08
  • it works, but the if (Raiz!=NULL) free(Raiz); still returning a invalid free. – Breno Santos Apr 14 '13 at 04:13
  • That warning means that you're using `NovaSubArvore` without declaring it. In that case, the compiler assumes that the return type of `NovaSubArvore` is an `int`, as @ShafikYaghmour points out above. You need to *declare* `NovaSubArvore` before you use it by putting a statement like `TipoApontador NovaSubArvore(int ordem);` somewhere before `main`, either in a .h file the .c file containing `main` includes, or just pasted directly in the .c file above `main`. (The .h approach is definitely better, stylistically.) – sigpwned Apr 14 '13 at 07:56
0

ok.... I think that it can't be done something like that:

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

This will get invalid free anyway. The rest of the problem it's solved by some answers there. I've accepted the most complete. But thanks everyone for trying to help!

Breno Santos
  • 174
  • 1
  • 3
  • 12