experchange > learn.c-c++

lalithaprasad (11-30-18, 01:22 PM)
#include <cstdio>
#include <cstdlib>
void f1(int **q){

*q=(int *)malloc(2*sizeof(int));
*q[0]=10;
*q[1]=20;
return;
}

int main(void){
int *p;
f1(&p);

printf("%d %d\n",*p,*(p+1));
return 0;
}

Please see the above program. When it is compiled with g++, it prints the first value correctly, but second value is garbage. I am unable to understand why it is so. My understanding was that malloc allocates memory from the heap and it will not be removed when the function returns, but that doesn'tseem to be happening. Can anybody clarify? Thanks in advance.

Lalitha Prasad
Ben Bacarisse (11-30-18, 01:44 PM)
lalithaprasad writes:

> #include <cstdio>
> #include <cstdlib>
> void f1(int **q){
> *q=(int *)malloc(2*sizeof(int));
> *q[0]=10;
> *q[1]=20;


This is parsed as

*(q[0]) = 10;
*(q[1]) = 20;

whereas what you meant was

(*q)[0] = 10;
(*q)[1] = 20;

Now E1[E2] means *((E1)+(E2)) so we can show that

*q[0] == *(q[0]) == *(*(q+0)) == *(*q) == *((*q) + 0) == (*q)[0]

In other words, it makes no difference for the first assignment. But
the other two, *(q[1]) and (*q)[1] are not at all the same thing. (I'll
leave you to think about why.)

> return;
> }
> int main(void){
> int *p;
> f1(&p);
> printf("%d %d\n",*p,*(p+1));


It's much more usual to write:

printf("%d %d\n", p[0], p[1]);

> return 0;
> }
> Please see the above program. When it is compiled with g++, it prints
> the first value correctly, but second value is garbage. I am unable to
> understand why it is so. My understanding was that malloc allocates
> memory from the heap and it will not be removed when the function
> returns, but that doesn't seem to be happening. Can anybody clarify?


The problem is not to do with the memory being released. It remains, as
you say, allocated until it is explicitly freed.

By the way, you are writing what is essentially C but using a C++
compiler. That's odd. A C++ program would usually use either a
container (like std::vector) or new in place of malloc.
Lalitha Prasad K (11-30-18, 06:22 PM)
On Friday, November 30, 2018 at 5:14:19 PM UTC+5:30, Ben Bacarisse wrote:
[..]
> container (like std::vector) or new in place of malloc.
> --
> Ben.


Thanks a lot for the clarification. I agree that it is a C program under the guise of a C++ program. I will take a relook at operator associativity and dereferencing.
Thanks once again

Lalitha Prasad
Stefan Ram (12-02-18, 03:14 PM)
Lalitha Prasad K <lalithaprasad> writes:
>I will take a relook at operator associativity


I subsume the rule about »*x[y]« under "precedence" ("priority").

For memorization, I memorize that postfix operators have higher
precedence than prefix operators.

In detail, the IBNF (=ASCII EBNF) from the standard looks
somewhat like my following simplification:

postfix-expression:
primary-expression
postfix-expression [ expression ]

unary-expression:
postfix-expression
unary-operator unary-expression

unary-operator: one of
& * + -  !
So, it can only be parsed as a unary expression, consisting
of the unary operator »*« and the unary-expression »x[y]«.
Stefan Ram (12-02-18, 03:16 PM)
Supersedes: <precedence-20181202141256>
[Repairing a misencoded character]

Lalitha Prasad K <lalithaprasad> writes:
>I will take a relook at operator associativity


I subsume the rule about »*x[y]« under "precedence" ("priority").

For memorization, I memorize that postfix operators have higher
precedence than prefix operators.

In detail, the IBNF (=ASCII EBNF) from the standard looks
somewhat like my following simplification:

postfix-expression:
primary-expression
postfix-expression [ expression ]

unary-expression:
postfix-expression
unary-operator unary-expression

unary-operator: one of
& * + - ~ !

»*x[y]« is not a postfix expression, as a postfix expression
cannot directly contain »*« by the above IBNF.

So, it can only be parsed as a unary expression, consisting
of the unary operator »*« and the unary-expression »x[y]«.
Ben Bacarisse (12-02-18, 06:13 PM)
ram (Stefan Ram) writes:

> Lalitha Prasad K <lalithaprasad> writes:
>>I will take a relook at operator associativity

> I subsume the rule about *x[y] under "precedence" ("priority").
> For memorization, I memorize that postfix operators have higher
> precedence than prefix operators.


And for remembering which way it goes (postfix first), remember that the
precedence is the one that makes sense for most of the prefix operators:

-ptr->quantity
~item.flags
!a[i]->data.processed
&a[i]

It's really only * that you might sometimes want to have higher
precedence.
Similar Threads