[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

pointer array

Wang WolfLouis

7/5/2011 3:09:00 PM


#include "stdafx.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

typedef struct {
char *data;
} pkt_buff_st;

typedef struct {
pkt_buff_st *pkt;
int isUsed;

} pkt_obj_st;

static pkt_obj_st *pkt_objs[5];

void pkt_obj_free(pkt_obj_st **pp)
{
pkt_obj_st *obj;
obj = *pp;

if (obj->pkt) {
free(obj->pkt->data);
free(obj->pkt);
obj->pkt = NULL;
}

free(*pp);
*pp = NULL;
}

void pkt_obj_print(void)
{
for (int i = 0; i < 5; i++) {
if (pkt_objs[i])
printf("pkt_objs[%d]: \n", i);
}
}

void set_pkt_obj(pkt_obj_st **set)
{
(*set) = NULL;
}

void pkt_buff_create(pkt_buff_st **one)
{
*one = (pkt_buff_st*)malloc(sizeof(pkt_buff_st));
}

int main(int argc, char* argv[])
{
pkt_buff_st *pkt01;
pkt_obj_st *obj01;

for (int j = 0; j < 5; j++) {
pkt_objs[j] = NULL;
}

pkt_buff_create(&pkt01);
pkt01->data = (char*)malloc(sizeof(char)*100);
memset(pkt01->data, '\0', 100);

obj01 = (pkt_obj_st*)malloc(sizeof(pkt_obj_st));

obj01->pkt = pkt01;
obj01->isUsed = 1;

for (int i = 0; i < 5; i++) {
pkt_objs[i] = obj01;
}
pkt_obj_print();

pkt_obj_free(&pkt_objs[2]);

//set_pkt_obj(&pkt_objs[2]);

pkt_obj_print();

// free(obj01);
// obj01 = NULL;


printf("Hello World!\n");
return 0;
}


if I change *pp = NULL in
void pkt_obj_free(pkt_obj_st **pp) function to obj = NULL, then
the pkt_objs pointer array didn't remove pkt_objs[2] pointer. I don't
know why? can anybody explain the reason?
6 Answers

Eric Sosman

7/5/2011 3:29:00 PM

0

On 7/5/2011 11:09 AM, Wang WolfLouis wrote:
> [...]
> void pkt_obj_free(pkt_obj_st **pp)
> {
> pkt_obj_st *obj;
> obj = *pp;
> [...]
> free(*pp);
> *pp = NULL;
> }
> [...]
> if I change *pp = NULL in
> void pkt_obj_free(pkt_obj_st **pp) function to obj = NULL, then
> the pkt_objs pointer array didn't remove pkt_objs[2] pointer. I don't
> know why? can anybody explain the reason?

`obj' is a variable local to pkt_obj_free, a variable whose
value is copied from `*pp'. If you copy a value and then change
the copy, you have not affected the original.

By the way, your code has other problems, too. One of those
is the use of a memory block that has already been free'd: When
you store `obj01' in all five positions of `ptr_obj[]', you are
not thereby creating five separate memory areas. Rather, you
are making five copies of a pointer to one malloc'ed memory area.
When you free that memory area, all five pointers (six, counting
the `obj01' original) become unusable. You set one of the five
to NULL, but the other four are still pointing to the vanished
memory -- yet the pkt_obj_print function will try to use them
anyhow, with unpredictable consequences. The commented-out
call to `free(obj01)' would also be Trouble with a capital T,
because the memory `obj01' points to has already been free'd.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Shao Miller

7/5/2011 3:38:00 PM

0

On 7/5/2011 11:09, Wang WolfLouis wrote:
>
> #include "stdafx.h"
> #include<string.h>
> #include<stdio.h>
> #include<stdlib.h>
> #include<memory.h>
>
> typedef struct {
> char *data;
> } pkt_buff_st;
>
> typedef struct {
> pkt_buff_st *pkt;
> int isUsed;
>
> } pkt_obj_st;
>
> static pkt_obj_st *pkt_objs[5];
>
> void pkt_obj_free(pkt_obj_st **pp)
> {
> pkt_obj_st *obj;
> obj = *pp;
>
> if (obj->pkt) {
> free(obj->pkt->data);
> free(obj->pkt);
> obj->pkt = NULL;
> }
>
> free(*pp);
> *pp = NULL;
> }
>
> void pkt_obj_print(void)
> {
> for (int i = 0; i< 5; i++) {
> if (pkt_objs[i])
> printf("pkt_objs[%d]: \n", i);
> }
> }
>
> void set_pkt_obj(pkt_obj_st **set)
> {
> (*set) = NULL;
> }
>
> void pkt_buff_create(pkt_buff_st **one)
> {
> *one = (pkt_buff_st*)malloc(sizeof(pkt_buff_st));
> }
>

Or the function above could have gone:

void pkt_buff_create(pkt_buff_st **one) {
*one = malloc(sizeof **one);
}

'malloc' returns a 'void *', which is suitable for assigning to any
pointer-to-object type; there's no need to cast.

> int main(int argc, char* argv[])
> {
> pkt_buff_st *pkt01;
> pkt_obj_st *obj01;
>
> for (int j = 0; j< 5; j++) {
> pkt_objs[j] = NULL;
> }
>
> pkt_buff_create(&pkt01);
> pkt01->data = (char*)malloc(sizeof(char)*100);

'sizeof (char)' is '1', by definition. So the line above could have gone:

pkt01->data = malloc(100);

instead.

> memset(pkt01->data, '\0', 100);
>
> obj01 = (pkt_obj_st*)malloc(sizeof(pkt_obj_st));
>
> obj01->pkt = pkt01;
> obj01->isUsed = 1;
>
> for (int i = 0; i< 5; i++) {
> pkt_objs[i] = obj01;
> }
> pkt_obj_print();
>
> pkt_obj_free(&pkt_objs[2]);
>
> //set_pkt_obj(&pkt_objs[2]);
>
> pkt_obj_print();
>
> // free(obj01);
> // obj01 = NULL;
>
>
> printf("Hello World!\n");
> return 0;
> }
>
>
> if I change *pp = NULL in
> void pkt_obj_free(pkt_obj_st **pp) function to obj = NULL, then
> the pkt_objs pointer array didn't remove pkt_objs[2] pointer. I don't
> know why? can anybody explain the reason?

'obj' is a _copy_ of '*pp'. The scope of 'obj' is the 'pkt_obj_free'
function. If you set 'obj' to 'NULL', that will not influence anything
outside of the function.

Does that help? I had a bit of difficulty understanding your question.

Wang WolfLouis

7/6/2011 1:50:00 AM

0

On 7?5?, ??11?29?, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 7/5/2011 11:09 AM, Wang WolfLouis wrote:
>
> > [...]
> > void pkt_obj_free(pkt_obj_st **pp)
> > {
> > pkt_obj_st *obj;
> > obj = *pp;
> > [...]
> > free(*pp);
> > *pp = NULL;
> > }
> > [...]
> > if I change *pp = NULL in
> > void pkt_obj_free(pkt_obj_st **pp) function to obj = NULL, then
> > the pkt_objs pointer array didn't remove pkt_objs[2] pointer. I don't
> > know why? can anybody explain the reason?
>
> `obj' is a variable local to pkt_obj_free, a variable whose
> value is copied from `*pp'. If you copy a value and then change
> the copy, you have not affected the original.
>
> By the way, your code has other problems, too. One of those
> is the use of a memory block that has already been free'd: When
> you store `obj01' in all five positions of `ptr_obj[]', you are
> not thereby creating five separate memory areas. Rather, you
> are making five copies of a pointer to one malloc'ed memory area.
> When you free that memory area, all five pointers (six, counting
> the `obj01' original) become unusable. You set one of the five
> to NULL, but the other four are still pointing to the vanished
> memory -- yet the pkt_obj_print function will try to use them
> anyhow, with unpredictable consequences. The commented-out
> call to `free(obj01)' would also be Trouble with a capital T,
> because the memory `obj01' points to has already been free'd.
>
> --
> Eric Sosman
> esos...@ieee-dot-org.invalid

Thnaks, Is obj is just a pointer copy of *pp? In other words, obj is
only a copy memeory
address of *pp, so obj->pkt->data can free the memory alloc by pkt01-
>data = (char*)malloc(sizeof(char)*100);

I want to free the pkt_objs pointer array refered to elements, for
example,
free pkt_objs[2] and set pkt_objs[2] = NULL. Then
for (i = 0; i < 5; i++) {
if (pkt_objs[i])
can known this array element have been freed. pkt_objs[2] can be
pointed to new alloced
pkt_obj_st pointer.
}
I only find the code as follows that could do the job:
void pkt_obj_free(pkt_obj_st **pp)
{
pkt_obj_st *obj;
obj = *pp;

if (obj->pkt) {
free(obj->pkt->data);
free(obj->pkt);
obj->pkt = NULL;
}

free(*pp);
*pp = NULL;

}
But it is ungly, have any other method do the job?

Shao Miller

7/6/2011 3:23:00 AM

0

On Tue, 5 Jul 2011 18:50:13 -0700 (PDT), Wang WolfLouis
<wolflouiswang@gmail.com> wrote:
> ...
> I only find the code as follows that could do the job:
> void pkt_obj_free(pkt_obj_st **pp)
> {
> pkt_obj_st *obj;
> obj = *pp;
> if (obj->pkt) {
> free(obj->pkt->data);
> free(obj->pkt);
> obj->pkt = NULL;
> }


> free(*pp);
> *pp = NULL;
> }
> But it is ungly, have any other method do the job?

Why use 'obj' at all?

void pkt_obj_free(pkt_obj_st ** pp) {
if ((*pp)->pkt) {
free((*pp)->pkt->data);
free((*pp)->pkt);
(*pp)->pkt = NULL;
}
free(*pp);
*pp = NULL;
}

io_x

7/6/2011 6:21:00 AM

0


"Wang WolfLouis" <wolflouiswang@gmail.com> ha scritto nel messaggio
news:5c5cfed6-7e78-48f5-aadb-e2ae28517d34@q12g2000prb.googlegroups.com...
>
> typedef struct {
> char *data;
> } pkt_buff_st;
>
> typedef struct {
> pkt_buff_st *pkt;
> int isUsed;
> } pkt_obj_st;
>
> static pkt_obj_st *pkt_objs[5];
>
> void pkt_obj_free(pkt_obj_st **pp)
> {
> pkt_obj_st *obj;
> obj = *pp;
>
> if (obj->pkt) {
> free(obj->pkt->data);
> free(obj->pkt);
> obj->pkt = NULL;
> }
>
> free(*pp);
> *pp = NULL;
> }
.....
> if I change *pp = NULL in
> void pkt_obj_free(pkt_obj_st **pp) function to obj = NULL, then
> the pkt_objs pointer array didn't remove pkt_objs[2] pointer. I don't
> know why? can anybody explain the reason?

if i have

pkt_obj_st *m;

m=malloc(1000);
pkt_obj_free(&m);

pp is the address[pointer] of one extern to function variable [m]
with
obj=*pp
i copy to obj the value of the extern variable
with
obj=NULL
copy to the local variable [to function ] obj the value 0.

pp point to the extern variable [m]
*pp=0
change the extern value [afther here m==0]




Eric Sosman

7/7/2011 1:37:00 AM

0

On 7/5/2011 9:50 PM, Wang WolfLouis wrote:
> [...]
> Thnaks, Is obj is just a pointer copy of *pp? In other words, obj is
> only a copy memeory
> address of *pp, so obj->pkt->data can free the memory alloc by pkt01-
>> data = (char*)malloc(sizeof(char)*100);

Yes. A pointer variable has a value, just as an int variable has a
value. You
can copy the value 42 from one int variable to another, and then modify the
second without changing what's in the first. You can copy the value
"pointer
to memory area A" from one pointer variable to another, and then change the
second without affecting the first.

*But* free(obj) doesn't change obj; it changes what obj points at
(by making
the pointed-at thing cease to exist, and allowing its memory to be
recycled for
other purposes). So after free(obj), objis unchanged but is also
unusable --
and so is the variable ptr's value was copied from.

Imagine that you have a friend's telephone number written on a piece of
paper in your wallet. At some point you decide to copy his number into your
cellphone's contact list; you now have two copies of his telephone number.
Now your friend moves to Outer Slobbovia where there is no phone service.
You still have both copies, but neither is of any use.

> I want to free the pkt_objs pointer array refered to elements, for
> example,
> free pkt_objs[2] and set pkt_objs[2] = NULL. Then
> for (i = 0; i< 5; i++) {
> if (pkt_objs[i])
> can known this array element have been freed. pkt_objs[2] can be
> pointed to new alloced
> pkt_obj_st pointer.

For the first part, yes: You can free(ptr) or free(pkt_objs[2]), and
both
will have the same effect since they both have the same value and point at
the same memory area. You can even set one or both of these variables
to NULL after the fact (like erasing your friend's old phone number). But
that won't change the values of pkt_objs[0], [1], [3], or [4]: They
still point at
the now-vanished memory, and their values are now out-of-date. It's as if
you had made six total copies of your friend's phone number and remembered
to erase one or two of them: The others are still recorded somewhere, but
are not useful.

> I only find the code as follows that could do the job:
> [...]
> But it is ungly, have any other method do the job?

I think you should gain more familiarity and ease with handling pointers
before you start worrying about ugliness. Learn to sing on pitch first, and
only then start studying the stylistic differences between Schubert and
Sting.

--
Eric Sosman
esosman@ieee-dot-org.invalid