|
List Info
Thread:
|
|
|
  Switzerland |
2007-11-09 09:41:12 |
Hi rooters,
can anyone explain me what the difference is
in between the following two line sets:
1)
const Float_t fgkAl3parameters[3] = {3., 4., 0.1};
Float_t *ccc;
for (Int_t ii=0; ii<3; ii++) ccc[ii] =
fgkAl3parameters[ii];
cout << ccc[0] << " " <<
ccc[1] << " " << ccc[2] <<
endl;
2)
const Float_t fgkAl3parameters[3] = {3., 4., 0.1};
Float_t *ccc = &fgkAl3parameters;
cout << ccc[0] << " " <<
ccc[1] << " " << ccc[2] <<
endl;
?
In ROOT framework:
if I use the first line set, I have a segmentation
violation;
if I use the second one, I haven't problem.
And again,
I made a macro (attached to this email):
this macro contains two methods,
one per each of the previously reported possibilities.
When I made the following:
.L proviamo.C
the compilation is ok,
but the first method execution ends with a segmentation
violation
and the execution of the second one ends correctly.
When I made the following:
.L proviamo.C++
the compilation stops with the following message:
./proviamo.C:31: error: cannot convert `const Float_t
(*)[3]' to `Float_t*' in initialization
If I comment the second method content,
the compilation ends correctly
and the first method execution also.
Thank you for you help
Best regards
Annalisa
|
|
|
| Re: arrays, pointers, and constness |
  Switzerland |
2007-11-09 10:04:15 |
Hi Annalisa,
Annalisa De Caro wrote:
> can anyone explain me what the difference is
> in between the following two line sets:
> 1)
> Float_t *ccc;
> for (Int_t ii=0; ii<3; ii++) ccc[ii] =
fgkAl3parameters[ii];
> 2)
> const Float_t fgkAl3parameters[3] = {3., 4., 0.1};
> Float_t *ccc = &fgkAl3parameters;
Case 1: let's take the iteration where ii==0. It puts the
value of
fgkAl3parameters[ii] into a new position in memory
("=", namely where
ccc points to plus 0 times the memory size that a Float_t
needs (that's
what "[0]" stands for). But where does ccc point
to? It's random! You
never set it to any value! In case 2, ccc is set to point to
the memory
address of fgkAl3parameters, so that's fine.
> And again,
> I made a macro (attached to this email):
> this macro contains two methods,
> one per each of the previously reported possibilities.
>
> When I made the following:
> .L proviamo.C
> the compilation is ok,
> but the first method execution ends with a segmentation
violation
You now know why.
> and the execution of the second one ends correctly.
That's because CINT is too nice - it does not check your
code properly.
If you run ".L proviamo.C+" or ".L
proviamo.C++", your compiler gets
invoked which is better in spotting code errors. And so it
complains:
> When I made the following:
> .L proviamo.C++
> the compilation stops with the following message:
> ./proviamo.C:31: error: cannot convert `const Float_t
(*)[3]' to `Float_t*' in initialization
You have an array of "const Float_t"s, and you try
to set ccc (a pointer
to a Float_t) by making it point to the array. That won't
work; ccc
doesn't respect the const-ness of the array values: the
array has const
Float_t, ccc doesn't. Make it "const Float_t *ccc"
instead.
> If I comment the second method content,
> the compilation ends correctly
> and the first method execution also.
If that's really the case then you're extremely lucky - ccc
is not
initialized, so it should usually just crash. But maybe ccc
was
accidentally, randomly pointing to some valid region of
memory....
Cheers, Axel.
|
|
| Re: |

|
2007-11-09 11:19:38 |
Hi Annalisa,
On Nov 9, 2007 7:41 AM, Annalisa De Caro
<Annalisa.de.Caro cern.ch> wrote:
> Hi rooters,
>
> can anyone explain me what the difference is
> in between the following two line sets:
>
> 1)
> const Float_t fgkAl3parameters[3] = {3., 4., 0.1};
> Float_t *ccc;
> for (Int_t ii=0; ii<3; ii++) ccc[ii] =
fgkAl3parameters[ii];
You declared a pointer to a Float_t, but never allocated
memory at the
location where the pointer points. Then you tried to set
the contents
of this non-existent memory. Thus the segfault. If you did
this in
the second line:
Float_t *ccc = new Float_t[3];
it should work OK.
(Of course, then you have the responsibility to delete []
the
allocated memory before ccc goes out of scope, in order to
avoid a
memory leak.)
> 2)
> const Float_t fgkAl3parameters[3] = {3., 4., 0.1};
> Float_t *ccc = &fgkAl3parameters;
At first glance, this is OK because the memory pointed to by
ccc is
already allocated as the array fgkAl3parameters. But you
should
really be declaring
Float_t * ccc = fgkAl3parameters;
(without the & operator) instead, since
fgkAl3parameters, as an array
of Float_t, can already be converted to a pointer to
Float_t. It
looks like CINT lets this slide, but the compiler is more
strict and
doesn't permit the error.
Hope this is helpful,
--
Kevin B. McCarty <kmccarty princeton.edu> Physics
Department
WWW: http://www.prince
ton.edu/~kmccarty/ Princeton University
GPG: public key ID 4F83C751 Princeton, NJ
08544
|
|
[1-3]
|
|