free const'ed memory without warning?

T

Tichodroma

#include <stdlib.h>
int main() {
const double
*x ;
x = (double *) malloc(4 * sizeof(double)) ;
free(x) ;
return 0 ;
}

Under gcc this generates a warning:

tmp.c:5: warning: passing argument 1 of ‘free’ discards qualifiers
from pointer target type

Should I understand from the warning that there's some other way I
should free const'ed memory, and if so how?

Thanks.
 
V

vippstar

#include <stdlib.h>
int main() {
const double
*x ;
x = (double *) malloc(4 * sizeof(double)) ;
free(x) ;
return 0 ;

}

Under gcc this generates a warning:

tmp.c:5: warning: passing argument 1 of ‘free’ discards qualifiers
from pointer target type

Should I understand from the warning that there's some other way I
should free const'ed memory, and if so how?

No, there's no problem with that.
Also, the cast in malloc (and it's good advice to do so) can be
dropped.
 
G

gw7rib

#include <stdlib.h>
int main() {
    const double
*x ;
    x = (double *) malloc(4 * sizeof(double)) ;
    free(x) ;
    return 0 ;

}

If x really is a pointer to const, then you won't be able to write
anything into the memory you've allocated, which rather defeats the
point of allocating it. Or more accurately, you will need to use a
cast or the like to write to the memory.

Might you want something along these lines?:

#include <stdlib.h>

void fillmemory(double *x);
void usememory(const double *x);

int main() {
double *x ;
x = malloc(4 * sizeof(double)) ;
fillmemory(x);
usememory(x);
free(x) ;
return 0 ;
}
 
D

dj3vande

Tichodroma said:
const double
*x ;
x = (double *) malloc(4 * sizeof(double)) ;

As noted elsethread, casting the return value of malloc is a Bad Idea;
it's never required and can hide errors.
free(x) ;
Under gcc this generates a warning:

tmp.c:5: warning: passing argument 1 of free discards qualifiers
from pointer target type

Should I understand from the warning that there's some other way I
should free const'ed memory, and if so how?

Giving it to free() is the correct way to deallocate memory you got
from malloc() and friends.

When I have a pointer that has had const (or volatile) qualifiers added
to it between getting it from malloc() and wanting to deallocate the
memory it points to, I like to write something like:
free((/*no const*/ void *)ptr);
to both shut up the compiler and inform other programmers about what
the cast is supposed to accomplish. (Casting to "/*no const*/ double *"
would be equally correct (assuming the pointer points at a double, as
it does in your example), but using "void *" (which the compiler will
convert it to when it calls free() anyways) gives me one less place
that needs the type of the variable written down.)


dave
(in That Other Language, it would be 'free(const_cast<T*>(ptr));',
except that in TOL you shouldn't be using malloc and free anyways.)
 
K

Keith Thompson

Tichodroma said:
#include <stdlib.h>
int main() {
const double
*x ;
x = (double *) malloc(4 * sizeof(double)) ;
free(x) ;
return 0 ;
}

Under gcc this generates a warning:

tmp.c:5: warning: passing argument 1 of ‘free’ discards qualifiers
from pointer target type

Should I understand from the warning that there's some other way I
should free const'ed memory, and if so how?

First, a couple of (mostly stylistic) suggestions:

"int main()" is better written as "int main(void)".

The malloc line is better written as:

x = malloc(4 * sizeof *x);

for reasons that have been explained here at length.

As to your question, what is the purpose of the "const" in the
declaration of x? It says that x is a pointer to a read-only object
of type double. If you're allocating an array of 4 doubles,
presumably you want to be able to write to them. And since calling
free() actually destroys the double objects, that violates their
constness. (The compiler doesn't necessarily know what free() does,
but it can see that there's no "const" in free's parameter
declaration.)

Usually when you declare a pointer to const <whatever>, you initialize
it to point to something that you don't intend to modify; the const
promises the compiler that you won't modify the target object via that
pointer.

You should use a double*, not a const double*, for malloc and free.
If you want to make a const double* visible to other code, so the
other code won't accidentally clobber the array elements, you can make
a copy of the double* pointer:

#include <stdlib.h>
int main(void)
{
double *private;
const double *public;
private = malloc(4 * sizeof *private);
public = private;

/*
* Do what you like with public *other than* modifying
* the array elements.
*/

free(private);
return 0;
}
 
C

CBFalconer

Tichodroma said:
#include <stdlib.h>
int main() {
const double *x ;
x = (double *) malloc(4 * sizeof(double)) ;
free(x) ;
return 0 ;
}

Under gcc this generates a warning:

tmp.c:5: warning: passing argument 1 of ‘free’ discards qualifiers
from pointer target type

Should I understand from the warning that there's some other way I
should free const'ed memory, and if so how?

You can't use const on a pointer to be malloced. It will be
necessary, sooner or later, to write into that memory before
reading it. The const prevents that. That error message may
confuse.

const items can only be initialized at definition time. For
function parameters, this is the moment of calling with a parameter
value.

BTW, never cast the value returned by malloc. All it does is
suppress warnings, which you need to see.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,088
Latest member
JeremyMedl

Latest Threads

Top