473,406 Members | 2,281 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,406 software developers and data experts.

accessing a struct

Hi,

What is the error in the code below? The output is:
DEBUG: matrix.b[0] is 2.000000
DEBUG: matrix->b[0] is 0.000000
In other words, the struct is empty after it is passed to the
solve_tridiag function. How can I fix this? I didn't see this in the
FAQ, although I have the feeling that I'm missing something basic here.

Many Thanks,
Michael Goerz
#include <stdio.h>

struct Tridiag{
// represents a tridiagonal matrix like this:
// b1 c1 0 0 0 ...
// a2 b2 c2 0 0 ...
// 0 a3 b3 c3 0 ...
// ... ...
double *a;
double *b;
double *c;
};
struct Tridiag create_matrix(){
struct Tridiag matrix;
double b[5] = { 2.0, 2.0, 2.0, 2.0, 2.0};
double a[5] = { 0.0, -1.0, -1.0, -1.0, -1.0};
double c[5] = {-1.0, -1.0, -1.0, -1.0, 0.0};
matrix.b = b;
matrix.a = a;
matrix.c = c;
return matrix;
}

void solve_tridiag( struct Tridiag *matrix, double *r){
printf("DEBUG: matrix->b[0] is %f\n", matrix->b[0]);
// ...
}
int main(){
double r[] = {0.0 , 1.0, 2.0, 3.0, 4.0};
struct Tridiag matrix = create_matrix();
printf("DEBUG: matrix.b[0] is %f\n", matrix.b[0]);
solve_tridiag(&matrix, r);
return 0;
}
Nov 11 '06 #1
4 2251
Michael Goerz wrote:
Hi,

What is the error in the code below? The output is:
DEBUG: matrix.b[0] is 2.000000
DEBUG: matrix->b[0] is 0.000000
In other words, the struct is empty after it is passed to the
solve_tridiag function. How can I fix this? I didn't see this in the
FAQ, although I have the feeling that I'm missing something basic here.

Many Thanks,
Michael Goerz
#include <stdio.h>

struct Tridiag{
// represents a tridiagonal matrix like this:
// b1 c1 0 0 0 ...
// a2 b2 c2 0 0 ...
// 0 a3 b3 c3 0 ...
// ... ...
double *a;
double *b;
double *c;
};
struct Tridiag create_matrix(){
struct Tridiag matrix;
double b[5] = { 2.0, 2.0, 2.0, 2.0, 2.0};
double a[5] = { 0.0, -1.0, -1.0, -1.0, -1.0};
double c[5] = {-1.0, -1.0, -1.0, -1.0, 0.0};
matrix.b = b;
matrix.a = a;
matrix.c = c;
return matrix;
}
So you saved the address of local arrays a, b and c onto data members
of matrix. Do you expect that the data these arrays point to after the
execution of this function will also be saved?
DEBUG: matrix->b[0] is 0.000000
void solve_tridiag( struct Tridiag *matrix, double *r){
printf("DEBUG: matrix->b[0] is %f\n", matrix->b[0]);
// ...
}
int main(){
double r[] = {0.0 , 1.0, 2.0, 3.0, 4.0};
struct Tridiag matrix = create_matrix();
printf("DEBUG: matrix.b[0] is %f\n", matrix.b[0]);
"DEBUG: matrix.b[0] is 2.000000"
Since you can access the saved data here, doesn't really means that
this data will be there for ever. After you finished executing
'create_matrix()' function, the memory used by these arrays is up for
grabs, your OS may use it as it needs it.
solve_tridiag(&matrix, r);
return 0;
}
I believe if you address these issues, your program should start
behaving.

Regards,
Manish

Nov 11 '06 #2
Michael Goerz <ne****@8439.e4ward.comwrote:
What is the error in the code below? The output is:
DEBUG: matrix.b[0] is 2.000000
DEBUG: matrix->b[0] is 0.000000
In other words, the struct is empty after it is passed to the
solve_tridiag function. How can I fix this? I didn't see this in the
FAQ, although I have the feeling that I'm missing something basic here.
#include <stdio.h>
struct Tridiag{
double *a;
double *b;
double *c;
};
struct Tridiag create_matrix(){
struct Tridiag matrix;
double b[5] = { 2.0, 2.0, 2.0, 2.0, 2.0};
double a[5] = { 0.0, -1.0, -1.0, -1.0, -1.0};
double c[5] = {-1.0, -1.0, -1.0, -1.0, 0.0};
matrix.b = b;
matrix.a = a;
matrix.c = c;
Now matrix.a, matrix.b and matrix.c are pointers to memory that is
local to this function. And once the function has ended they point
to memory you don't own anymore since the three arrays have gone
out of scope.
return matrix;
}
void solve_tridiag( struct Tridiag *matrix, double *r){
printf("DEBUG: matrix->b[0] is %f\n", matrix->b[0]);
}
int main(){
Better make that

int main( void )
double r[] = {0.0 , 1.0, 2.0, 3.0, 4.0};
struct Tridiag matrix = create_matrix();
printf("DEBUG: matrix.b[0] is %f\n", matrix.b[0]);
This only works by accident. Probably the data of the three arrays
the elements of matrix point to still are undisturbed on the stack,
so it may look as everything is fine, but you're just unlucky. If
you would try the same program on a different machine it could al-
ready give you an "unexpected" result here.
solve_tridiag(&matrix, r);
And now calling another function overwrites things on the stack and
you finally find out about the errors of your way;-) Bugs where one
uses memory that one doesn't own can be hard to find since it can
look like nothing bad happened for a long time, only to result in
a weird problem somewhere else, seemingly completely unrelated to
where the original error was.
return 0;
}
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Nov 11 '06 #3
Michael Goerz wrote:
Hi,

What is the error in the code below? The output is:
DEBUG: matrix.b[0] is 2.000000
DEBUG: matrix->b[0] is 0.000000
In other words, the struct is empty after it is passed to the
solve_tridiag function. How can I fix this? I didn't see this in the
FAQ, although I have the feeling that I'm missing something basic here.
It's Question 7.5a, but somewhat disguised. The FAQ's
example has a function returning a pointer value that points
to one of the function's auto variables, and since the variable
ceases to exist when the function returns the pointer is no
good to the caller. You're not doing exactly that, but ...
#include <stdio.h>

struct Tridiag{
// represents a tridiagonal matrix like this:
// b1 c1 0 0 0 ...
// a2 b2 c2 0 0 ...
// 0 a3 b3 c3 0 ...
// ... ...
double *a;
double *b;
double *c;
};
struct Tridiag create_matrix(){
struct Tridiag matrix;
double b[5] = { 2.0, 2.0, 2.0, 2.0, 2.0};
double a[5] = { 0.0, -1.0, -1.0, -1.0, -1.0};
double c[5] = {-1.0, -1.0, -1.0, -1.0, 0.0};
All of b, a, c will cease to exist when create_matrix()
returns, just as in the FAQ's example.
matrix.b = b;
matrix.a = a;
matrix.c = c;
return matrix;
There's nothing wrong with returning the struct value
`matrix', but matrix.b, matrix.a, matrix.c are pointing to
b, a, c, which are about to expire ...
}
Solution: You need the struct elements to point to storage
that will survive after create_matrix() has been and gone, and
for as long as you still need the values. One possibility is
to use static storage, as illustrated in the FAQ. Another is
to call malloc() to obtain dynamic storage that will hold the
values provided by create_matrix(); it would be a good idea to
write a companion destroy_matrix() to free() the dynamic memory
when you're done with it. Hard to say which approach is more
suitable; in the "toy" program you've shown static storage is
easier, but I imagine you have more involved applications in
mind.

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 11 '06 #4
Hello Michael,
What is the error in the code below? The output is:
DEBUG: matrix.b[0] is 2.000000
DEBUG: matrix->b[0] is 0.000000
In other words, the struct is empty after it is passed to the
solve_tridiag function. How can I fix this? I didn't see this in the
FAQ, although I have the feeling that I'm missing something basic here.
<snip>
struct Tridiag create_matrix(){
struct Tridiag matrix;
double b[5] = { 2.0, 2.0, 2.0, 2.0, 2.0};
double a[5] = { 0.0, -1.0, -1.0, -1.0, -1.0};
double c[5] = {-1.0, -1.0, -1.0, -1.0, 0.0};
matrix.b = b;
matrix.a = a;
matrix.c = c;
return matrix;
}
Here is your problem. The pointer matrix.b,matrix.a,matrix.c of your
Tridiag structure point to the *local* variables (ie. located on the
stack) b,a,c resp. The life of those variables is only limited to the
function create_matrix(). And soon as the function returns, the values
are undefined. That's actually the effect your are seeing.

You can fix your code as follow. You can declare the variable b,a,c in
create_matrix() as static. Or you can allocate with malloc()/calloc()
enough room for matrix.b,matrix.a,matrix.c and you copy the contents of
b,a,c as appropriate with memcpy().

HTH,
Loic.

Nov 11 '06 #5

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

Similar topics

0
by: S.Tobias | last post by:
Quote from 6.5.2.3 Structure and union members, Examle 3: The following is not a valid fragment (because the union type is not visible within function f): struct t1 { int m; }; struct t2 {...
47
by: fb | last post by:
Hi Everyone. Thanks for the help with the qudratic equation problem...I didn't think about actually doing the math...whoops. Anyway... I'm having some trouble getting the following program to...
2
by: Walter Deodiaus | last post by:
I have typedef struct { union _union{ .... struct { int i; }u1; .... }Union; } Struct ;
5
by: pt | last post by:
Hi, i am wonderng what is faster according to accessing speed to read these data structure from the disk in c/c++ including alignment handling if we access it on little endian system 32 bits...
1
by: rashmi | last post by:
Dear All, Here is the small program that i am trying to do : #include<stdio.h> #include<stdlib.h> #include<string.h> struct nested_struct { char *name; }; struct some
5
by: Andy | last post by:
I'm having trouble accessing an unmanaged long from a managed class in VC++.NET When I do, the contents of the variable seem to be mangled. If I access the same variable byte-by-byte, I get the...
14
by: Kavya | last post by:
Here is the code int main(){ struct node{ int a; int b; int c; }; struct node s={3,5,6}; struct node *ptr=&s;
4
by: Alan | last post by:
I`m having trouble figuring out the correct syntax for accessing an element of a struct variable (t_list) passed by reference to a function. The compiler does not like the code below when I added...
1
by: kenchu.osu | last post by:
Hi folks, I have a question about accessing the member of a build-in struct. Eg. struct { struct { int x; int y;
0
by: MukeshChoudhari | last post by:
Hi, I have a struct in my application. public struct MyStruct { int a; public int b; } As C# says struct members are public by default, but I am not able to access this member in my main...
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...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.