pointer array

W

Wang WolfLouis

#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)
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 = 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?
 
E

Eric Sosman

[...]
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.
 
S

Shao Miller

#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)
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 = 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.
 
W

Wang WolfLouis

[...]
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.

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)
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?
 
S

Shao Miller

...
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;
}
 
E

Eric Sosman

[...]
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)
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.
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top