How to assign memory dynamically to a array of structures

S

skumar434

Hi everybody,

I am faceing problem while assigning the memory dynamically to a array
of structures .
Suppose I have a structure

typedef struct hom_id{

int32_t nod_de;
int32_t hom_id;
int32_t hom_type;
int32_t hom_pid;
} hom_data;

I created array of structures in my program so that i can store the
data in array

hom_data arr[];

I want to know how to assign memory to this array of structure at
runtime.

Can anybody point waht is wrong with this code .
I able to compile it but its printing garbage values.

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

typedef struct hom_id{

int32_t nod_de;
int32_t hom_id;
int32_t hom_type;
int32_t hom_pid;
} hom_data;

int main()
{
FILE *fout;

hom_data hom[30];---->how to allocate memory to this array of stuct
dynamically.
int i=0;

/* open input file and test to see if it is empty */
if ((fout = fopen("momtext.txt", "r")) == NULL) {
printf("error ---- file read is empty\n\n");
exit(1); }

/* open output file */
fout = fopen("momtext.txt", "r");
while (fscanf (fout ,"%08x %08x ", &hom.nod_de, &hom.hom_id)
!= 2)
{

fscanf(fout ,"%08x %08x", &hom.hom_type, &hom.hom_pid );
printf("%08x %08x ", hom.nod_de, hom.hom_id);
printf("%s %s %s\n", hom.hom_type, hom.hom_pid);
i++;

}
return 0;


}


Thanks in advance
 
R

Richard Heathfield

(e-mail address removed) said:
Hi everybody,

I am faceing problem while assigning the memory dynamically to a array
of structures .

#include <stdlib.h>
#include <stdio.h>

struct T
{
int this;
int class;
int teaches;
int dynamic;
int memory;
int allocation;
};

int main(void)
{
size_t capacity = 32;
size_t count = 0;
char line[256] = {0};

/* allocate a bunch of structs to start off with */
struct T *p = malloc(capacity * sizeof *p);
if(p != NULL)
{
while(fgets(line, sizeof line, stdin) != NULL)
{
if(count >= capacity)
{
struct T *new = realloc(p, capacity * 2 * sizeof *new);
if(new != NULL)
{
p = new;
capacity *= 2;
}
else
{
/* take some kind of corrective action, or simply... */
fprintf(stderr,
"Couldn't allocate sufficient memory"
" for %lu items.\n",
(unsigned long)capacity * 2);
exit(EXIT_FAILURE);
}
}
if(sscanf(line,
"%d %d %d %d %d %d",
&p[count].this,
&p[count].class,
&p[count].teaches,
&p[count].dynamic,
&p[count].memory,
&p[count].allocation) != 6)
{
fprintf(stderr,
"Input error on line %lu\n",
(unsigned long)count);
exit(EXIT_FAILURE);
}
++count;
}

/* display sums in reverse order */
while(count-- > 0)
{
int sum = p[count].this;
sum += p[count].class;
sum += p[count].teaches;
sum += p[count].dynamic;
sum += p[count].memory;
sum += p[count].allocation;
printf("%d\n", sum);
}

free(p);
}
else
{
fprintf(stderr, "Couldn't allocate memory\n");
}
return 0;
}
 
K

Keith Thompson

I am faceing problem while assigning the memory dynamically to a array
of structures .

This look awfully familiar. Haven't you started several other threads
about this same problem? Why not just post a followup in the original
thread?
Suppose I have a structure

typedef struct hom_id{

int32_t nod_de;
int32_t hom_id;
int32_t hom_type;
int32_t hom_pid;
} hom_data;

Your struct tag "hom_id" is the same as the name of one of your struct
members. This is legal but confusing.

If you insist on using a typedef for your structure, and it doesn't
contain any pointers to the same type, you don't actually need the
tag:

typedef struct {
/* members */
} hom_data;

Or you can use the same identifier for the struct tag and the typedef:

typedef struct hom_data {
/* members */
} hom_data;

Personally, I'd drop the typedef and just refer to the type as "struct
hom_data", but a lot of people like typedefs for various reasons.
I created array of structures in my program so that i can store the
data in array

hom_data arr[];

I want to know how to assign memory to this array of structure at
runtime.

Can anybody point waht is wrong with this code .
I able to compile it but its printing garbage values.

#include <stdio.h>
#include <stdint.h>
#include <string.h>
Ok.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

These last 4 headers are not defined in standard C; they're
Unix-specific. If you actually used anything from them, I'd tell you
to try comp.unix.programmer. But as far as I can tell you're not, so
you can just delete them (at least in code you post here).
typedef struct hom_id{

int32_t nod_de;
int32_t hom_id;
int32_t hom_type;
int32_t hom_pid;
} hom_data;

int main()

Better:
int main(void)
{
FILE *fout;

hom_data hom[30];---->how to allocate memory to this array of stuct
dynamically.
int i=0;

/* open input file and test to see if it is empty */
if ((fout = fopen("momtext.txt", "r")) == NULL) {
printf("error ---- file read is empty\n\n");
exit(1); }

exit() is declared in <stdlib.h>; you need a #include for it. If your
compiler didn't warn you about that, turn up the warning level.

exit(1) is non-portable. Use exit(EXIT_FAILURE).
/* open output file */
fout = fopen("momtext.txt", "r");

What? You just opened this file (and checked the result of fopen();
good for you). Now you open it again for reading, but your commment
says "open output file", and you don't check the result.

And why do you call it "fout" when it's used for input?
while (fscanf (fout ,"%08x %08x ", &hom.nod_de, &hom.hom_id)
!= 2)
{

fscanf(fout ,"%08x %08x", &hom.hom_type, &hom.hom_pid );


You checked the result of the first fscanf(), but not the second.
Always check the result of fscanf(). I think you're assuming there
will be no errors in your input file; that's a dangerous assumption.

Maybe you should use a single fcanf() to read all 4 value.

(I'd use fgets() followed by sscanf(); use fscanf() directly should
work, but it doesn't give you much flexibility in dealing with
errors.)
printf("%08x %08x ", hom.nod_de, hom.hom_id);


The "%08x" format for both fscanf() and printf() specifies an argument
of type unsigned int (or pointer to unsigned int for fscanf()).
You're using arguments of type int32_t, which may or may not be the
same type. <inttypes.h> provides format specifiers for int32_t, but
it's unwieldy. For output, use "%08lx" and cast the arguments to
unsigned long. For input, you can read into temporaries of type
unsigned long and then assign to your uint32_t members.
printf("%s %s %s\n", hom.hom_type, hom.hom_pid);


You tell printf you're going to give it three char* arguments pointing
to strings, then you give it two int32_t arguments. Of course you're
getting garbage.
i++;

}
return 0;


}

Your real question was about how to dynamically allocate an array of
structures, when the number of structures you need is going to depend
on an input file (i.e., you don't know in advance).

You can either use malloc() to allocate an array, then use realloc()
to grow it as needed (and *always* check the value returned by both
functions), or you can use malloc() allocate one record at a time and
add each one to a linked list. (The latter isn't an array, which is
what you asked for, but it might suit your purposes. If not, you
could also build the linked list, then once you know how big it is you
can use a single malloc() to allocate an array and copy the linked
list elements into it. This does increase your memory requirements,
though.)

For a first draft, though, you might just declare a fixed-size array
and store values into it, keeping track of how many elements are being
used. This will fail if the input is too big, but it should be easier
to implement, and it will give you a chance to fix all the other
errors in your code before you start worrying about memory allocation.
 
S

skumar434

Hi there,
As per your suggestion i wrote this code .Here i am tring to copy each
line from the file into a structure .And passing it to a function which
creates a linked list and stores the values in it.

Now the problem is i am getting a segmentatin fault error , I think its
comming in the addnode_hom(); function.

-> I am not able to rectify the problem .
->Is due to that i am tring to use same structure for creating a linked
list and passing the data to the function.

-> I am tring but not getting the solution.

-> can u help me


#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct {
int32_t hom_node;
int32_t hom_id;
int32_t hom_rest;
int32_t hom_type;
struct hom_id *link;
}hom_data;

int addnode_hom (hom_data *homptr);
void printnode_data (hom_data *h_ptr);
int count(hom_data *h_ptr);

int main(void)
{
FILE *fp;
int count = 0;
int ret;
char buff[1024];
hom_data *homptr;
homptr = (struct hom_data *) malloc(sizeof(hom_data));
//printf("test_main1\n");
fp = popen("grep 0044 momtext.txt","r");
//printf("test_main\n");
while(fgets(buff,sizeof(buff),fp)!=NULL){
fscanf(fp,"%08x %08x %04x %08x",&homptr->hom_node,
&homptr->hom_id,
&homptr->hom_rest,
&homptr->hom_type);
ret = addnode_hom(homptr);
if(ret == 0)
{
printf("error\n");
exit(1);
}
else {
/*printf("%08x %08x %04x %08x\n",homptr->hom_node,
homptr->hom_id,
homptr->hom_rest,
homptr->hom_type);*/
count++;
}


printf("%d\n",count);
free(homptr);
pclose(fp);
return 0;
}
}

void printnode_data (hom_data *h_ptr) {
//printf("test_print\n");
if(h_ptr == NULL){
printf("flie is empty ");

}
else{

printf("%08x %08x %04x %08x\n",h_ptr->hom_node,
h_ptr->hom_id,
h_ptr->hom_rest,
h_ptr->hom_rest,
h_ptr->hom_type);


printf ("\n");
}

}


int addnode_hom (hom_data * homptr){

hom_data *h_ptr,*current,*new;
int ctr;
ctr=count(h_ptr);
if(ctr == 0){
h_ptr = (struct hom_data *) malloc (sizeof(hom_data));
if(h_ptr == NULL){
printf("error");}
memset(h_ptr, 0, sizeof(hom_data));
//current = h_ptr;

h_ptr->hom_node = homptr->hom_node;
h_ptr->hom_id = homptr->hom_id;
h_ptr->hom_rest = homptr->hom_rest;
h_ptr->hom_type = homptr->hom_type;
h_ptr->link = NULL;
}
else{
current = (struct hom_data)malloc(sizeof(hom_data));
current = h_ptr;
while(current->link != NULL)
current=current->link;
}
new=(struct hom_data *)malloc(sizeof(hom_data));
memset(current,0,sizeof(hom_data));
current->link=new;
new->hom_node = homptr->hom_node;
new->hom_id = homptr->hom_id;
new->hom_rest = homptr->hom_rest;
new->hom_type = homptr->hom_type;
new->link = NULL;
current=new;
printnode_data(current);

}

int count(hom_data *h_ptr)
{
int ctr=0;
while(h_ptr->link != NULL)
{
h_ptr = h_ptr->link;
ctr++;
}
return ctr;
}





Keith said:
I am faceing problem while assigning the memory dynamically to a array
of structures .

This look awfully familiar. Haven't you started several other threads
about this same problem? Why not just post a followup in the original
thread?
Suppose I have a structure

typedef struct hom_id{

int32_t nod_de;
int32_t hom_id;
int32_t hom_type;
int32_t hom_pid;
} hom_data;

Your struct tag "hom_id" is the same as the name of one of your struct
members. This is legal but confusing.

If you insist on using a typedef for your structure, and it doesn't
contain any pointers to the same type, you don't actually need the
tag:

typedef struct {
/* members */
} hom_data;

Or you can use the same identifier for the struct tag and the typedef:

typedef struct hom_data {
/* members */
} hom_data;

Personally, I'd drop the typedef and just refer to the type as "struct
hom_data", but a lot of people like typedefs for various reasons.
I created array of structures in my program so that i can store the
data in array

hom_data arr[];

I want to know how to assign memory to this array of structure at
runtime.

Can anybody point waht is wrong with this code .
I able to compile it but its printing garbage values.

#include <stdio.h>
#include <stdint.h>
#include <string.h>
Ok.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

These last 4 headers are not defined in standard C; they're
Unix-specific. If you actually used anything from them, I'd tell you
to try comp.unix.programmer. But as far as I can tell you're not, so
you can just delete them (at least in code you post here).
typedef struct hom_id{

int32_t nod_de;
int32_t hom_id;
int32_t hom_type;
int32_t hom_pid;
} hom_data;

int main()

Better:
int main(void)
{
FILE *fout;

hom_data hom[30];---->how to allocate memory to this array of stuct
dynamically.
int i=0;

/* open input file and test to see if it is empty */
if ((fout = fopen("momtext.txt", "r")) == NULL) {
printf("error ---- file read is empty\n\n");
exit(1); }

exit() is declared in <stdlib.h>; you need a #include for it. If your
compiler didn't warn you about that, turn up the warning level.

exit(1) is non-portable. Use exit(EXIT_FAILURE).
/* open output file */
fout = fopen("momtext.txt", "r");

What? You just opened this file (and checked the result of fopen();
good for you). Now you open it again for reading, but your commment
says "open output file", and you don't check the result.

And why do you call it "fout" when it's used for input?
while (fscanf (fout ,"%08x %08x ", &hom.nod_de, &hom.hom_id)
!= 2)
{

fscanf(fout ,"%08x %08x", &hom.hom_type, &hom.hom_pid );


You checked the result of the first fscanf(), but not the second.
Always check the result of fscanf(). I think you're assuming there
will be no errors in your input file; that's a dangerous assumption.

Maybe you should use a single fcanf() to read all 4 value.

(I'd use fgets() followed by sscanf(); use fscanf() directly should
work, but it doesn't give you much flexibility in dealing with
errors.)
printf("%08x %08x ", hom.nod_de, hom.hom_id);


The "%08x" format for both fscanf() and printf() specifies an argument
of type unsigned int (or pointer to unsigned int for fscanf()).
You're using arguments of type int32_t, which may or may not be the
same type. <inttypes.h> provides format specifiers for int32_t, but
it's unwieldy. For output, use "%08lx" and cast the arguments to
unsigned long. For input, you can read into temporaries of type
unsigned long and then assign to your uint32_t members.
printf("%s %s %s\n", hom.hom_type, hom.hom_pid);


You tell printf you're going to give it three char* arguments pointing
to strings, then you give it two int32_t arguments. Of course you're
getting garbage.
i++;

}
return 0;


}

Your real question was about how to dynamically allocate an array of
structures, when the number of structures you need is going to depend
on an input file (i.e., you don't know in advance).

You can either use malloc() to allocate an array, then use realloc()
to grow it as needed (and *always* check the value returned by both
functions), or you can use malloc() allocate one record at a time and
add each one to a linked list. (The latter isn't an array, which is
what you asked for, but it might suit your purposes. If not, you
could also build the linked list, then once you know how big it is you
can use a single malloc() to allocate an array and copy the linked
list elements into it. This does increase your memory requirements,
though.)

For a first draft, though, you might just declare a fixed-size array
and store values into it, keeping track of how many elements are being
used. This will fail if the input is too big, but it should be easier
to implement, and it will give you a chance to fix all the other
errors in your code before you start worrying about memory allocation.
 
P

pete

Hi there,
As per your suggestion i wrote this code .Here i am tring to copy each
line from the file into a structure .
And passing it to a function which
creates a linked list and stores the values in it.

Here's a program that shows one way how to do that:

/* BEGIN line_to_string.c */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>

struct list_node {
struct list_node *next;
void *data;
};

int line_to_string(FILE *fp, char **line, size_t *size);
void list_free(struct list_node *node, void (*free_data)(void *));
void list_fprint(FILE *stream, struct list_node *node);
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data);

int main(void)
{
struct list_node *head, *tail;
int rc;
char *buff_ptr;
size_t buff_size;
long unsigned line_count;

puts(
"\nThis program makes and prints a list of all the lines\n"
"of text entered from the standard input stream.\n"
"Just hit the Enter key to end,\n"
"or enter any line of characters to continue."
);
tail = head = NULL;
line_count = 0;
buff_size = 0;
buff_ptr = NULL;
while ((rc = line_to_string(stdin, &buff_ptr, &buff_size)) > 1) {
++line_count;
tail = string_node(&head, tail, buff_ptr);
if (tail == NULL) {
break;
}
puts(
"\nJust hit the Enter key to end,\n"
"or enter any other line of characters to continue."
);
}
switch (rc) {
case EOF:
if (buff_ptr != NULL && strlen(buff_ptr) > 0) {
puts("rc equals EOF\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
case 0:
puts("realloc returned a null pointer value");
if (buff_size > 1) {
puts("rc equals 0\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
default:
break;
}
if (line_count != 0 && tail == NULL) {
puts("Node allocation failed.");
puts("The last line entered didnt't make it onto the list:");
puts(buff_ptr);
}
free(buff_ptr);
puts("\nThe line buffer has been freed.\n");
printf("%lu lines of text were entered.\n", line_count);
puts("They are:\n");
list_fprint(stdout, head);
list_free(head, free);
puts("\nThe list has been freed.\n");
return 0;
}

int line_to_string(FILE *fp, char **line, size_t *size)
{
int rc;
void *p;
size_t count;

count = 0;
while ((rc = getc(fp)) != EOF) {
++count;
if (count + 2 > *size) {
p = realloc(*line, count + 2);
if (p == NULL) {
if (*size > count) {
(*line)[count] = '\0';
(*line)[count - 1] = (char)rc;
} else {
ungetc(rc, fp);
}
count = 0;
break;
}
*line = p;
*size = count + 2;
}
if (rc == '\n') {
(*line)[count - 1] = '\0';
break;
}
(*line)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count > INT_MAX ? INT_MAX : count;
} else {
if (*size > count) {
(*line)[count] = '\0';
}
}
return rc;
}

void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;

while (node != NULL) {
next_node = node -> next;
free_data(node -> data);
free(node);
node = next_node;
}
}

void list_fprint(FILE *stream, struct list_node *node)
{
while (node != NULL) {
fputs(node -> data, stream);
putc('\n', stream);
node = node -> next;
}
}

struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data)
{
struct list_node *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -> next = NULL;
node -> data = malloc(strlen(data) + 1);
if (node -> data != NULL) {
if (*head == NULL) {
*head = node;
} else {
tail -> next = node;
}
strcpy(node -> data, data);
} else {
free(node);
node = NULL;
}
}
return node;
}

/* END line_to_string.c */
 
P

pete

pete said:
while ((rc = line_to_string(stdin, &buff_ptr, &buff_size)) > 1) {

rc is either EOF or the number of bytes in the resulting string.
The above line of code was written to terminate the loop
when the length of the string is zero, in other words,
when there is one byte in the string.
You probably would want to chage the condition to

while ((rc = line_to_string(stdin, &buff_ptr, &buff_size)) > 0) {

for use with an ordinary text file.
 
S

skumar434

pete said:
rc is either EOF or the number of bytes in the resulting string.
The above line of code was written to terminate the loop
when the length of the string is zero, in other words,
when there is one byte in the string.
You probably would want to chage the condition to

while ((rc = line_to_string(stdin, &buff_ptr, &buff_size)) > 0) {

for use with an ordinary text file.

Thanks for the code .But there is one more think i have to ask

I am getting this error while compiling the program,which i have
written .Can any body just tell why I am getting this .


tet.c: In function `addnode_hom':
tet.c:78: parse error before `else'
tet.c: At top level:
tet.c:92: parse error before `}'


Tcode is
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

struct data{
int32_t hom_id;
int32_t hom_rest;
struct data *link;
}*hom_data;

void addnode_hom (int32_t *hom_id,int32_t *hom_rest);
void printnode_data ();
//int count(hom_data *h_ptr);

int main(void)
{
FILE *fp;
int count = 0;
int32_t hom_node;
int32_t hom_id;
int32_t hom_rest;
int32_t hom_type;
char buff[1024];
//hom_data *homptr;
//homptr = (struct hom_data *) malloc(sizeof(hom_data));
//printf("test_main1\n");

fp = popen("grep 0044 momtext.txt","r");
//printf("test_main\n");
while(fgets(buff,sizeof(buff),fp)!=NULL){
fscanf(fp,"%08x %08x %04x %08x",&hom_node,
&hom_id,
&hom_rest,
&hom_type);
addnode_hom((int32_t*)hom_id,(int32_t*)hom_rest);

count++;
}


printf("%d\n",count);
// free(hom_data);
// pclose(fp);
return 0;
}

void printnode_data () {
struct data *current;
current = hom_data;

while(current->link!=NULL)
{
printf(" %08x %04x \n",hom_data->hom_id,
hom_data->hom_rest);
}
}


void addnode_hom (int32_t *hom_id , int32_t *hom_rest)
{
struct data *current,*new;
new = (struct data *)malloc(sizeof(struct data));
if ( hom_data == NULL)
{
hom_data = (struct data *)malloc(sizeof(struct data));
//memset(hom_data, 0, sizeof(struct data));
current = hom_data;
else{
current = hom_data;
while (current->link!=NULL)
{
current=current->link;
}
}
current = (struct data *)malloc(sizeof(struct data));
current->link=new;

current->hom_id = hom_data->hom_id;
current->hom_rest = hom_data->hom_rest;
//new->link=NULL;
}
}
 
F

Flash Gordon

(e-mail address removed) wrote:

I am getting this error while compiling the program,which i have
written .Can any body just tell why I am getting this .


tet.c: In function `addnode_hom':
tet.c:78: parse error before `else'

So perhaps you should look at line 78 and above?
tet.c: At top level:
tet.c:92: parse error before `}'

if ( hom_data == NULL)
{
hom_data = (struct data *)malloc(sizeof(struct data));
//memset(hom_data, 0, sizeof(struct data));
current = hom_data;
else{

<snip>

If you actually indented your code even vaguely sensibly, i.e. increased
the indentation level as you go in to blocks, the problem would be
obvious. People indent for a reason!

if ( hom_data == NULL)
{
hom_data = (struct data *)malloc(sizeof(struct data));
//memset(hom_data, 0, sizeof(struct data));
current = hom_data;
else {

The above is reindented more sensibly. You should now be able to see the
problem.

Indentation is a style issue, but I don't know anyone who would not
consider yours terrible.

Also, I'm sure someone must have told you about not casting the return
value of malloc. If not, read the FAQ and search the group for far
better ways to use malloc.
 
H

Herbert Rosenau

Hi there,
As per your suggestion i wrote this code .Here i am tring to copy each
line from the file into a structure .And passing it to a function which
creates a linked list and stores the values in it.

Now the problem is i am getting a segmentatin fault error , I think its
comming in the addnode_hom(); function.

-> I am not able to rectify the problem .
->Is due to that i am tring to use same structure for creating a linked
list and passing the data to the function.

-> I am tring but not getting the solution.

-> can u help me


#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct {
int32_t hom_node;
int32_t hom_id;
int32_t hom_rest;
int32_t hom_type;
struct hom_id *link;
}hom_data;

int addnode_hom (hom_data *homptr);
void printnode_data (hom_data *h_ptr);
int count(hom_data *h_ptr);

int main(void)
{
FILE *fp;
int count = 0;
int ret;
char buff[1024];
hom_data *homptr;
homptr = (struct hom_data *) malloc(sizeof(hom_data));

How often should we tell you:

NEVER EVER ccast the result of malloc(). It will hide some errors and
may send you in the lands of undefined behavior.

casts are the most dangerous featers of C. Never use a cast - ecxept
you knows exactly what you does, and even then check and recheck if
the cast is really needed. And thereafter, when you means you needs a
cast you mostenly wrong again.

Never use a cast because the compiler comlains! Be sure you understund
really what the compiler will tell you. Mostenly he does NOT tell you
you should use a cast. It will tell you that you have done a mistake
but seldom you has to cast something. So check again what you've done
and fix it without a cast. Cast only, really only when you're really
and absolutely sure that you really and absolutely knows what you are
doing and why the cast is really neccessary.
//printf("test_main1\n");
fp = popen("grep 0044 momtext.txt","r");
//printf("test_main\n");
while(fgets(buff,sizeof(buff),fp)!=NULL){
fscanf(fp,"%08x %08x %04x %08x",&homptr->hom_node,
&homptr->hom_id,
&homptr->hom_rest,
&homptr->hom_type);

You've forgotten tho test the result of fscanf.
ret = addnode_hom(homptr);
if(ret == 0)
{
printf("error\n");
exit(1);
}
else {
/*printf("%08x %08x %04x %08x\n",homptr->hom_node,
homptr->hom_id,
homptr->hom_rest,
homptr->hom_type);*/
count++;
}


printf("%d\n",count);
free(homptr);
pclose(fp);
return 0;
}
}

void printnode_data (hom_data *h_ptr) {
//printf("test_print\n");
if(h_ptr == NULL){
printf("flie is empty ");

}
else{

printf("%08x %08x %04x %08x\n",h_ptr->hom_node,
h_ptr->hom_id,
h_ptr->hom_rest,
h_ptr->hom_rest,
h_ptr->hom_type);


printf ("\n");
}

}


int addnode_hom (hom_data * homptr){

hom_data *h_ptr,*current,*new;
int ctr;
ctr=count(h_ptr);
if(ctr == 0){
h_ptr = (struct hom_data *) malloc (sizeof(hom_data));
if(h_ptr == NULL){

same as above.
printf("error");}
memset(h_ptr, 0, sizeof(hom_data));

memset is mostenly leading to undefined behavior. Setting an array of
bytes to 0 is no guarantee to get pointers, ints and other nonbyte
values set to propper value but will result in trap representations.
So aboid memset for structs and other non byte values to avoid
failtures.
//current = h_ptr;

h_ptr->hom_node = homptr->hom_node;
h_ptr->hom_id = homptr->hom_id;
h_ptr->hom_rest = homptr->hom_rest;
h_ptr->hom_type = homptr->hom_type;
h_ptr->link = NULL;
}
else{
current = (struct hom_data)malloc(sizeof(hom_data));

See above.
current = h_ptr;
while(current->link != NULL)
current=current->link;
}
new=(struct hom_data *)malloc(sizeof(hom_data));
memset(current,0,sizeof(hom_data));
current->link=new;
new->hom_node = homptr->hom_node;
new->hom_id = homptr->hom_id;
new->hom_rest = homptr->hom_rest;
new->hom_type = homptr->hom_type;
new->link = NULL;
current=new;
printnode_data(current);

}

int count(hom_data *h_ptr)
{
int ctr=0;
while(h_ptr->link != NULL)
{
h_ptr = h_ptr->link;
ctr++;
}
return ctr;
}


Your indents makes it impossible to identify the block levels, making
it too hard to understund what the logic of your program is.

At lest: DON'T TOPPOPST. Remove anything you have no comment for. Use
clean indent.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
K

Keith Thompson

Herbert Rosenau said:
]
NEVER EVER ccast the result of malloc(). It will hide some errors and
may send you in the lands of undefined behavior.

That's good advice, but the cast itself, *if* it casts the result to
the correct type, does not invoke undefined behavior.

A cast can mask an error, and is therefore usually a bad idea. But it
does not itself create the error. And in the very rare cases where it
makes sense to write code that will compile as either C or C++, a cast
is necessary and, if done *very* carefully, can be safe.

It's important to be clear about *why* casting the result of malloc()
is a bad idea.

[...]
memset is mostenly leading to undefined behavior. Setting an array of
bytes to 0 is no guarantee to get pointers, ints and other nonbyte
values set to propper value but will result in trap representations.
So aboid memset for structs and other non byte values to avoid
failtures.

(The word is "mostly", not "mostenly".)

You can almost certainly assume that all-bits-zero is a representation
of 0 for any integer type. This is not stated in the C90 or C99
standard, but n1124 adds this wording:

For any integer type, the object representation where all the bits
are zero shall be a representation of the value zero in that type.

I don't believe there are any existing implementations that don't
already follow this rule (which is why the committee felt it was safe
to add this requirement).

Having said that, it's not necessarily a good idea to use memset() on
structures. Even if all the members are integers, or even unsigned
char, it's easy to add, say, a pointer or floating-point member later
and forget about the memset().

You can always declare a const object to be used to initialize the
structure to "zero":

const struct foo foo_zero = { 0 };

(Or you can use a compound literal, but only if you can assume C99.)
 
B

Barry Schwarz

Hi there,
As per your suggestion i wrote this code .Here i am tring to copy each
line from the file into a structure .And passing it to a function which
creates a linked list and stores the values in it.

Now the problem is i am getting a segmentatin fault error , I think its
comming in the addnode_hom(); function.

Did you run your code under a debugger?

Since your code does not compile cleanly, why did you execute it at
all?
-> I am not able to rectify the problem .
->Is due to that i am tring to use same structure for creating a linked
list and passing the data to the function.

-> I am tring but not getting the solution.

-> can u help me


#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct {
int32_t hom_node;
int32_t hom_id;
int32_t hom_rest;
int32_t hom_type;
struct hom_id *link;

There is no struct hom_id.
}hom_data;

int addnode_hom (hom_data *homptr);
void printnode_data (hom_data *h_ptr);
int count(hom_data *h_ptr);

int main(void)
{
FILE *fp;
int count = 0;
int ret;
char buff[1024];
hom_data *homptr;
homptr = (struct hom_data *) malloc(sizeof(hom_data));

There is no type struct hom_data. There is a type hom_data which is
an alias for a tagless struct.

Why are you casting the return from malloc?
//printf("test_main1\n");
fp = popen("grep 0044 momtext.txt","r");

popen is not a standard function. Did you mean fopen?
//printf("test_main\n");
while(fgets(buff,sizeof(buff),fp)!=NULL){
fscanf(fp,"%08x %08x %04x %08x",&homptr->hom_node,
&homptr->hom_id,
&homptr->hom_rest,
&homptr->hom_type);
ret = addnode_hom(homptr);
if(ret == 0)
{
printf("error\n");
exit(1);
}
else {

If the range of an if includes any statement that prevents the code
from flowing out of the range, the else serves no purpose.
/*printf("%08x %08x %04x %08x\n",homptr->hom_node,
homptr->hom_id,
homptr->hom_rest,
homptr->hom_type);*/
count++;
}


printf("%d\n",count);
free(homptr);
pclose(fp);

pclose is not a standard function. Did you mean fclose?
return 0;
}
}

void printnode_data (hom_data *h_ptr) {
//printf("test_print\n");
if(h_ptr == NULL){
printf("flie is empty ");

}
else{

printf("%08x %08x %04x %08x\n",h_ptr->hom_node,
h_ptr->hom_id,
h_ptr->hom_rest,
h_ptr->hom_rest,
h_ptr->hom_type);


printf ("\n");
}

}


int addnode_hom (hom_data * homptr){

hom_data *h_ptr,*current,*new;
int ctr;
ctr=count(h_ptr);
if(ctr == 0){
h_ptr = (struct hom_data *) malloc (sizeof(hom_data));
if(h_ptr == NULL){
printf("error");}
memset(h_ptr, 0, sizeof(hom_data));
//current = h_ptr;

h_ptr->hom_node = homptr->hom_node;
h_ptr->hom_id = homptr->hom_id;
h_ptr->hom_rest = homptr->hom_rest;
h_ptr->hom_type = homptr->hom_type;
h_ptr->link = NULL;
}
else{
current = (struct hom_data)malloc(sizeof(hom_data));
current = h_ptr;
while(current->link != NULL)
current=current->link;

current is a pointer to hom_data. link is a pointer to a struct
hom_id. There is no implied conversion between the two.
}
new=(struct hom_data *)malloc(sizeof(hom_data));
memset(current,0,sizeof(hom_data));
current->link=new;
new->hom_node = homptr->hom_node;
new->hom_id = homptr->hom_id;
new->hom_rest = homptr->hom_rest;
new->hom_type = homptr->hom_type;
new->link = NULL;
current=new;
printnode_data(current);

}

int count(hom_data *h_ptr)
{
int ctr=0;
while(h_ptr->link != NULL)
{
h_ptr = h_ptr->link;
ctr++;
}
return ctr;
}


Remove del for email
 

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,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top