473,385 Members | 1,445 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

A question on C structures

I've a structure:
struct msghdr
{
//some goes here

struct iovec *msg_iov;

//some more ---
}

struct msghdr msg;
The body of struct iovec looks like this:
struct iovec
{
void *iov_base; // to point to a (char *) buffer
int iov_len;
}
I declare a struct iovec array:
struct iovec iov[10];

Then fill it with values after proper memory allocation:

for i: 0 to 9
strcpy(iov[i].iov_base, buf);
iov[i].iov_len = length;

Then i make *msg_iov to point to this array:
msg.msg_iov = iov;

my question is when i try to access iov_base by:
msg.msg_iov[i].iov_base
it works only for i=0, for the rest it shows NULL.

Now the interesting part, when i pass the
address of 'msg' to a display function (display(struct msghdr *msg))
then in that function i'm able to access the buffers without any problem
using,
msg->msg_iov[i].iov_base
Isn't this weird?
Why will a 'access method' make any difference
Any suggestion/clarifications are welcome.
Nov 14 '05 #1
11 1651
nishant a couché sur son écran :
struct msghdr
{
struct iovec *msg_iov;
}

struct msghdr msg;

struct iovec
{
void *iov_base; // to point to a (char *) buffer
int iov_len;
}

my question is when i try to access iov_base by:
msg.msg_iov[i].iov_base
it works only for i=0, for the rest it shows NULL.

Now the interesting part, when i pass the
address of 'msg' to a display function (display(struct msghdr *msg))
then in that function i'm able to access the buffers without any problem
using,
msg->msg_iov[i].iov_base

Isn't this weird?
No, it's not.
Why will a 'access method' make any difference
Any suggestion/clarifications are welcome.


Because you passed the address of the structure (Which is The Good Way)
via a pointer. The access is now 'indirect'. For clarification, I
suggest that you change your definition for

display (struct msghdr *p_msg)
{
<...>
p_msg->msg_iov[i].iov_base
}

or (probably better, at last to me)

display (struct msghdr *this)
{
<...>
this->msg_iov[i].iov_base
}

--
Emmanuel

Nov 14 '05 #2
On 19 Jul 2004 21:54:56 -0700, ni*******@gmail.com (nishant) wrote:

snip disjointed code fragments
my question is when i try to access iov_base by:
msg.msg_iov[i].iov_base
it works only for i=0, for the rest it shows NULL.

Now the interesting part, when i pass the
address of 'msg' to a display function (display(struct msghdr *msg))
then in that function i'm able to access the buffers without any problem
using,
msg->msg_iov[i].iov_base
Isn't this weird?
Why will a 'access method' make any difference
Any suggestion/clarifications are welcome.


You need to post a compilable example that illustrates the behavior
you describe.
<<Remove the del for email>>
Nov 14 '05 #3


nishant wrote:
I've a structure:
struct msghdr
{
//some goes here

struct iovec *msg_iov;

//some more ---
}

struct msghdr msg;
The body of struct iovec looks like this:
struct iovec
{
void *iov_base; // to point to a (char *) buffer
int iov_len;
}
I declare a struct iovec array:
struct iovec iov[10];

Then fill it with values after proper memory allocation:

for i: 0 to 9
strcpy(iov[i].iov_base, buf);
iov[i].iov_len = length;

Then i make *msg_iov to point to this array:
msg.msg_iov = iov;

my question is when i try to access iov_base by:
msg.msg_iov[i].iov_base
it works only for i=0, for the rest it shows NULL.
This doen't seem right. Your syntax, msg.msg_iov[i].iov_base,
looks fine. I am assuming that all 10 of the dynamic allocations
were successful since the strcpy worked in the loop. There must
be something else involved.

See the example
Now the interesting part, when i pass the
address of 'msg' to a display function (display(struct msghdr *msg))
then in that function i'm able to access the buffers without any problem
using,
msg->msg_iov[i].iov_base

Isn't this weird? Your use of the -> operator is correct. I guess your 'weird' comment
is because the . operator is not working but the -> is working
as expected. It appears to me that you are using the operators
corrected.
Why will a 'access method' make any difference
Any suggestion/clarifications are welcome.


The example:

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

#define SZ 10

struct iovec
{
void *iov_base; // to point to a (char *) buffer
size_t iov_len;
};

struct msghdr
{
//some goes here

struct iovec *msg_iov;

//some more ---
};

void FreeMsghdr(struct msghdr *msg)
{
int i;

for(i = 0; i < SZ; i++)
{
free(msg->msg_iov[i].iov_base);
msg->msg_iov[i].iov_base = NULL;
msg->msg_iov[i].iov_len = 0;
}
msg->msg_iov = NULL;
return;
}

int main(void)
{
struct msghdr msg;
struct iovec iov[SZ];
int i;
char buf[32];

for(i = 0; i < SZ;i++)
{
iov[i].iov_base = malloc(32);
if(iov[i].iov_base)
{
sprintf(buf,"HelloWorld_%d",i);
strcpy(iov[i].iov_base,buf);
iov[i].iov_len = strlen(buf);
}
}
msg.msg_iov = iov;
for(i = 0;i < SZ;i++)
printf("msg.msg_iov[%d].iov_base = \"%s\"\n",i,
msg.msg_iov[i].iov_base?msg.msg_iov[i].iov_base:"NULL");
FreeMsghdr(&msg);
puts("\nAfter Calling FreeMsghdr:");
for(i = 0;i < SZ;i++)
printf("iov[%d].iov_base = %s\t\t"
"iov[%d].iov_len = %u\n",i,
iov[i].iov_base?iov[i].iov_base:"NULL",
i,iov[i].iov_len);
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #4
In the function void FreeMsghdr(struct msghdr *msg), isn't it enough
by calling free()? Why would we still need

msg->msg_iov[i].iov_base = NULL;
msg->msg_iov[i].iov_len = 0;

and

msg->msg_iov = NULL;

I remember I saw this before but have no idea why we need them.
Al Bowers <xa******@rapidsys.com> wrote in message news:<2m************@uni-berlin.de>...
nishant wrote:
I've a structure:
struct msghdr

[snip]

The example:

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

#define SZ 10

struct iovec
{
void *iov_base; // to point to a (char *) buffer
size_t iov_len;
};

struct msghdr
{
//some goes here

struct iovec *msg_iov;

//some more ---
};

void FreeMsghdr(struct msghdr *msg)
{
int i;

for(i = 0; i < SZ; i++)
{
free(msg->msg_iov[i].iov_base);
msg->msg_iov[i].iov_base = NULL;
msg->msg_iov[i].iov_len = 0;
}
msg->msg_iov = NULL;
return;
}

int main(void)
{
struct msghdr msg;
struct iovec iov[SZ];
int i;
char buf[32];

for(i = 0; i < SZ;i++)
{
iov[i].iov_base = malloc(32);
if(iov[i].iov_base)
{
sprintf(buf,"HelloWorld_%d",i);
strcpy(iov[i].iov_base,buf);
iov[i].iov_len = strlen(buf);
}
}
msg.msg_iov = iov;
for(i = 0;i < SZ;i++)
printf("msg.msg_iov[%d].iov_base = \"%s\"\n",i,
msg.msg_iov[i].iov_base?msg.msg_iov[i].iov_base:"NULL");
FreeMsghdr(&msg);
puts("\nAfter Calling FreeMsghdr:");
for(i = 0;i < SZ;i++)
printf("iov[%d].iov_base = %s\t\t"
"iov[%d].iov_len = %u\n",i,
iov[i].iov_base?iov[i].iov_base:"NULL",
i,iov[i].iov_len);
return 0;
}

Nov 14 '05 #5
salut Emmanuel
i'm sorry if i made u couché (i hope my french is correct :-) )
Thank you for replying. but the question still remains ---

Emmanuel Delahaye <em***@YOURBRAnoos.fr> wrote in message news:<mn***********************@YOURBRAnoos.fr>...
nishant a couché sur son écran :
-----------
Now the interesting part, when i pass the
address of 'msg' to a display function (display(struct msghdr *msg))
then in that function i'm able to access the buffers without any problem
using,
msg->msg_iov[i].iov_base

Isn't this weird?
No, it's not.
Why will a 'access method' make any difference
Any suggestion/clarifications are welcome.


Because you passed the address of the structure (Which is The Good Way)
via a pointer. The access is now 'indirect'. For clarification, I
suggest that you change your definition for


i will restate my question,
A method whether 'direct' or 'indirect' shudn't make any difference
when accessing a value, right?
if i can access it thru a pointer then why not by the variable itself
??

display (struct msghdr *p_msg)
{
<...>
p_msg->msg_iov[i].iov_base
}

or (probably better, at last to me)

display (struct msghdr *this)
{
<...>
this->msg_iov[i].iov_base
}

Nov 14 '05 #6
Hello Al
Thank you for replying.
But The question still remains
Now the interesting part, when i pass the
address of 'msg' to a display function (display(struct msghdr *msg))
then in that function i'm able to access the buffers without any problem
using,
msg->msg_iov[i].iov_base

Isn't this weird?

Your use of the -> operator is correct. I guess your 'weird' comment
is because the . operator is not working but the -> is working
as expected.


You are Right, Any explanantions for that ?
I even tried cleaning up the memory first before assigning anything as
you suggested. But even that doesn't work.
Nov 14 '05 #7


nishant wrote:
Hello Al
Thank you for replying.
But The question still remains

Now the interesting part, when i pass the
address of 'msg' to a display function (display(struct msghdr *msg))
then in that function i'm able to access the buffers without any problem
using,
msg->msg_iov[i].iov_base

Isn't this weird?


Your use of the -> operator is correct. I guess your 'weird' comment
is because the . operator is not working but the -> is working
as expected.

You are Right, Any explanantions for that ?
I even tried cleaning up the memory first before assigning anything as
you suggested. But even that doesn't work.


From the info you have provided, I cannot give an explanation.

You have:
1. Provided the declarations and assignments for the structs.
They seem fine.
2. Shown that you have an understanding of the . operator and the
-> operation and the their usage.

Yet! The . operator is not working and the -> is working.

This leaves me to believe that there is a suble error in the code
that you have yet to uncover.

I would suggest that you simply the code, still showing 'weird'
behavior, to a form that would allow you to post it.
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #8


Xingbo G wrote:
In the function void FreeMsghdr(struct msghdr *msg), isn't it enough
by calling free()? Why would we still need

msg->msg_iov[i].iov_base = NULL;
msg->msg_iov[i].iov_len = 0;

and

msg->msg_iov = NULL;


It is not needed. It is not neccessary, especially in the trival
example. It is more like a 'religion'.

In the design of a function that frees dynamic memory in objects,
some feel that it best not leave dangling pointers that could
lead to problems in a complex, large code project. So, the pointers
and other members of the struct are given a value that can asseverate
the condition of the object elsewhere in the code.
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #9
Hi Al,
I include the code below, if this is what u want.
The program makes use of socket calls to accept a connection and then
recieve some data. The 'weird' part is with the the " /*### "
comments.
I hope this time the 'weird'ness is clear to you.
#include <stdio.h>
#include <------->

#define PORT 6000
#define BUFNUM 3
#define BUFLEN 20
#define BACKLOG 15

/* int recvmsg(int, struct msghdr, int)
Description: It is used to receive an array of buffers (from the
socket interface specified by int s)
and copy it to struct msghdr *mesghdr */
int recvmsg(int s, struct msghdr *mesghdr, int flags)
{
char *buf;
int i,j, bufsize, fromlen;
struct sockaddr_in from_addr;
struct iovec iov[BUFNUM];

fromlen = sizeof(struct sockaddr_in);
buf = (char *)malloc(BUFLEN+1);
bufsize = BUFLEN+1;

for(j=0; j<BUFNUM; j++)
{
iov[j].iov_base = (char *)malloc(BUFLEN);
iov[j].iov_len = BUFLEN;
}

for(j=0; j<BUFNUM; j++) // keep recieving BUFNUM times
{
i = recvfrom(s,buf,bufsize,flags,&from_addr,&fromlen); // a
socket call
strcpy(iov[j].iov_base, buf);
iov[j].iov_len = bufsize;
}

mesghdr->msg_iov = iov;

mesghdr->msg_name = (void *)&from_addr;
mesghdr->msg_namelen = fromlen;
mesghdr->msg_iovlen = BUFNUM;

return (i);

}

void display(struct msghdr *msg) // takes the address of msghdr
{
int i;
char recvdata[BUFNUM][BUFLEN];
for(i=0; i<BUFNUM && strcmp(msg->msg_iov[i].iov_base,"") != 0;
i++)
{
strcpy(recvdata[i], msg->msg_iov[i].iov_base); /* ###
'->'works fine */
printf("\nMessage Received %d: %s\n", i+1,
recvdata[i]);
}
}

void main()
{
int new_fd, sockfd, i;
int sockin_size;
char recvdata[BUFNUM][BUFLEN];

struct msghdr mesghdr;
struct sockaddr_in local_addr, remote_addr;

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
{
printf("Sockfd error\n");
exit(0);
}

local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(PORT);
local_addr.sin_addr.s_addr = INADDR_ANY;
/*local_addr.sin_addr.s_addr = inet_addr("172.31.41.17");
*/

memset(&(local_addr.sin_zero),'\0', 8); /* Required */

if( bind(sockfd, (struct sockaddr *)&local_addr, sizeof(struct
sockaddr)) == -1)
{
printf("BIND ERROR\n");
exit(0);
}

if( listen(sockfd, BACKLOG) == -1)
{
printf("LISTEN ERROR\n");
exit(0);
}

sockin_size = sizeof(struct sockaddr_in);
printf("\n before accept \n");
new_fd = accept(sockfd, (struct sockaddr *) &remote_addr,
&sockin_size);
printf("\n after accept \n");

printf("server: got connection from
%s\n",inet_ntoa(remote_addr.sin_addr));
memset(mesghdr, 0, sizeof (struct msghdr));
mesghdr.msg_name = (void *)malloc(sizeof(struct sockaddr));
mesghdr.msg_namelen = sizeof(struct sockaddr);
mesghdr.msg_iovlen = BUFNUM;

if(( i = recvmsg(new_fd,(struct msghdr *)&mesghdr,0)) == -1 )
{
perror("recvmsg error: ");
printf("Error No: %d\n", errno);
exit(0);
}

/* for(i=0; i<BUFNUM && strcmp(mesghdr.msg_iov[i].iov_base," ")
!= 0; i++)
{
strcpy(recvdata[i], mesghdr.msg_iov[i].iov_base); /*### '.'doesn't
work */
printf("\nMessage Received %d: %s\n", i+1, recvdata[i]);
} */

display((struct msghdr *)&mesghdr); // included this since the above
doesn't work

printf("\n");

close(sockfd);
}

********************* structure body ***************************
struct msghdr
{
//some goes here

struct iovec *msg_iov;

//some more ---
}msg;

struct iovec
{
void *iov_base; // to point to a (char *) buffer
int iov_len;
}iov[10];
Nov 14 '05 #10


nishant wrote:

There are a number of problem areas that I want memtion.
However, here is one that I will address as a serious flaw.

In the function recvmsg (definition below), you declare a struct
object iov. This object is visible only within that function.
int recvmsg(int s, struct msghdr *mesghdr, int flags)
{
char *buf;
int i,j, bufsize, fromlen;
struct sockaddr_in from_addr;
struct iovec iov[BUFNUM];

fromlen = sizeof(struct sockaddr_in);
buf = (char *)malloc(BUFLEN+1);
bufsize = BUFLEN+1;

for(j=0; j<BUFNUM; j++)
{
iov[j].iov_base = (char *)malloc(BUFLEN);
iov[j].iov_len = BUFLEN;
}

for(j=0; j<BUFNUM; j++) // keep recieving BUFNUM times
{
i = recvfrom(s,buf,bufsize,flags,&from_addr,&fromlen); // a
socket call
strcpy(iov[j].iov_base, buf);
iov[j].iov_len = bufsize;
}

mesghdr->msg_iov = iov;
Oops! You have assigned a member of an object declared in function
main a value that will be meaningless once function recvfrom exits. iov
ceases its existence at function exit.

mesghdr->msg_name = (void *)&from_addr;
mesghdr->msg_namelen = fromlen;
mesghdr->msg_iovlen = BUFNUM;

return (i);

}
void main()
{
int new_fd, sockfd, i;
int sockin_size;
char recvdata[BUFNUM][BUFLEN];

struct msghdr mesghdr;
struct sockaddr_in local_addr, remote_addr;
................snip...............

if(( i = recvmsg(new_fd,(struct msghdr *)&mesghdr,0)) == -1 )
{
perror("recvmsg error: ");
printf("Error No: %d\n", errno);
exit(0);
}

/* for(i=0; i<BUFNUM && strcmp(mesghdr.msg_iov[i].iov_base," ")
!= 0; i++)
{
strcpy(recvdata[i], mesghdr.msg_iov[i].iov_base); /*### '.'doesn't
work */
Since the value mesghdr.msg_iov represents a pointer to storage
that may no longer exist, all bets are off and it is not surprising
that it doesn't work.

printf("\nMessage Received %d: %s\n", i+1, recvdata[i]);
} */

display((struct msghdr *)&mesghdr); // included this since the above
doesn't work

printf("\n");

close(sockfd);
}

********************* structure body ***************************
struct msghdr
{
//some goes here

struct iovec *msg_iov;

//some more ---
}msg;
This global struct object, msg, may be causing confusion.
I do not see it being used in your code snippet.

struct iovec
{
void *iov_base; // to point to a (char *) buffer
int iov_len;
}iov[10];


Same here with iov.
Get rid of both globals, msg and iov. Declare the struct objects
in function main and redesign the functions to use these objects.

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #11
Hello Al,
Thanks a bunch.
I got the mistake i was making.

mesghdr->msg_iov = iov;


Oops! You have assigned a member of an object declared in function
main a value that will be meaningless once function recvfrom exits. iov
ceases its existence at function exit.


You hit the nail on the head !
struct msghdr
{
//some goes here

struct iovec *msg_iov;

//some more ---
}msg;


This global struct object, msg, may be causing confusion.
I do not see it being used in your code snippet.

struct iovec
{
void *iov_base; // to point to a (char *) buffer
int iov_len;
}iov[10];


Same here with iov.
Get rid of both globals, msg and iov. Declare the struct objects
in function main and redesign the functions to use these objects.

well, these structs were just for ur reference. i'm not using them in the prog
Nov 14 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: kazack | last post by:
Hi all it's me again with another question as I got further in my book. The chapter I am in covers structres, abstract data and classes. I only read through to the end of the coverage on...
33
by: Peter Seaman | last post by:
I understand that structures are value types and arrays and classes are reference types. But what about arrays as members of structures i.e. as in C struct x { int n; int a; }
6
by: Ken Allen | last post by:
OK, I admit that I have been programming since before C++ was invented, and I have developed more than my share of assembly language systems, and even contributed to operating system and compiler...
7
by: John Dann | last post by:
I'm trying to read some binary data from a file created by another program. I know the binary file format but can't change or control the format. The binary data is organised such that it should...
14
by: pmclinn | last post by:
I've noticed that many programmers use classes to store data about such things like: Class Customers .....Phone ....ID ....Address End Class....
2
by: thomasfarrow | last post by:
At work, our development team has a development standards document that insists Structures should never be used. I'm looking to change this standard but need a suitable argument in order to make...
11
by: efrat | last post by:
Hello, I'm planning to use Python in order to teach a DSA (data structures and algorithms) course in an academic institute. If you could help out with the following questions, I'd sure...
44
by: svata | last post by:
Hello, I wonder how to resize such array of structures using realloc()? #include <stdio.h> #include <stdlib.h> #define FIRST 7 typedef struct { char *name;
4
by: cleanrabbit | last post by:
Hello! I hate having to do this, because im almost certain there is someone in the world that has come across this problem and i just havent found their solution yet, so i do appologise if this...
8
by: Bob Altman | last post by:
Hi all, I have a structure that includes a constructor. I want to add a bunch of these structures to an STL map (whose index is an int). If I define the map like this: map<int,...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.