Structures and Pointers

S

Sally

I am confused as to why the code below does not produce a segmenation
fault. It actually works, and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

I noticed also if I do use malloc, then free(ptr), I can still use
ptr->z and assign to z successfully?

struct myStruct {
char x[10];
char y[1000];
int z;
};

int main(..) {

struct myStruct *ptr;

ptr->z = 12;
printf("%d",prt->z);

}
 
J

Joona I Palaste

Sally said:
I am confused as to why the code below does not produce a segmenation
fault. It actually works, and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

It works by accident. The code invokes undefined behaviour, but
undefined behaviour does not automatically mean segmentation
faults. If you try it in different circumstances, it might very well
crash.
I noticed also if I do use malloc, then free(ptr), I can still use
ptr->z and assign to z successfully?

The same reasoning applies.
struct myStruct {
char x[10];
char y[1000];
int z;
};
int main(..) {
struct myStruct *ptr;
 
M

Mike Wahler

Sally said:
I am confused as to why the code below does not produce a segmenation
fault.

It's not required to.
It actually works

By (unfortunate) accident. This time.
and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

You do if you want your program's behavior to be
well-defined and predictable, with guarantees from
the language standard about its behavior.
I noticed also if I do use malloc, then free(ptr), I can still use
ptr->z and assign to z successfully?

struct myStruct {
char x[10];
char y[1000];
int z;
};

int main(..) {

struct myStruct *ptr;

ptr->z = 12;
printf("%d",prt->z);

}

The above is an example of 'undefined behavior'. According to
the language standard, the compiler is allowed to produce
code that does *anything*. This can vary from a violent
crash, to 'seeming to work' (and theoretically such things
as the ubiquitous 'nasal demons'). In your case, it 'seems
to work.' Next time it might do something completely different.
Murphy's law dictates that this will happen when the application
is first demonstrated to a potential client.

Moral: Don't Do That.

You also have another case of undefined behavior:
invocation of 'printf()' with no prototype in scope.

And you need a return statement for main().

-Mike
 
M

Mark A. Odell

(e-mail address removed) (Sally) wrote in

I am confused as to why the code below does not produce a segmenation
fault. It actually works, and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

You got (un)lucky. You do need to use malloc() in this case. What you did
is wrong.
I noticed also if I do use malloc, then free(ptr), I can still use
ptr->z and assign to z successfully?

Again, do not do this. If it works as hoped it's just luck.
struct myStruct {
char x[10];
char y[1000];
int z;
};

int main(..) {

struct myStruct *ptr;

ptr->z = 12;

Do *not* do this.
 
J

Joe Laughlin

Mike said:
Sally said:
I am confused as to why the code below does not produce
a segmenation fault.

It's not required to.
It actually works

By (unfortunate) accident. This time.
and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

You do if you want your program's behavior to be
well-defined and predictable, with guarantees from
the language standard about its behavior.
I noticed also if I do use malloc, then free(ptr), I can
still use ptr->z and assign to z successfully?

struct myStruct {
char x[10];
char y[1000];
int z;
};

int main(..) {

struct myStruct *ptr;

ptr->z = 12;
printf("%d",prt->z);

}
You also have another case of undefined behavior:
invocation of 'printf()' with no prototype in scope.

You need to include a prototype for each function that you use?
 
J

Joona I Palaste

Joe Laughlin said:
Mike said:
Sally said:
I am confused as to why the code below does not produce
a segmenation fault.

It's not required to.
It actually works

By (unfortunate) accident. This time.
and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

You do if you want your program's behavior to be
well-defined and predictable, with guarantees from
the language standard about its behavior.
I noticed also if I do use malloc, then free(ptr), I can
still use ptr->z and assign to z successfully?

struct myStruct {
char x[10];
char y[1000];
int z;
};

int main(..) {

struct myStruct *ptr;

ptr->z = 12;
printf("%d",prt->z);

}
You also have another case of undefined behavior:
invocation of 'printf()' with no prototype in scope.
You need to include a prototype for each function that you use?

Yes, you do. In C99 at least. A full definition constitutes a
prototype, however a mere declaration does not always do so.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Remember: There are only three kinds of people - those who can count and those
who can't."
- Vampyra
 
S

Sam Dennis

Joe said:
You need to include a prototype for each function that you use?

No, but you do need to for all variadic functions. It's a good idea
regardless, however.
 
K

Kieran Simkin

Joe Laughlin said:
Mike said:
Sally said:
I am confused as to why the code below does not produce
a segmenation fault.

It's not required to.
It actually works

By (unfortunate) accident. This time.
and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

You do if you want your program's behavior to be
well-defined and predictable, with guarantees from
the language standard about its behavior.
I noticed also if I do use malloc, then free(ptr), I can
still use ptr->z and assign to z successfully?

struct myStruct {
char x[10];
char y[1000];
int z;
};

int main(..) {

struct myStruct *ptr;

ptr->z = 12;
printf("%d",prt->z);

}
You also have another case of undefined behavior:
invocation of 'printf()' with no prototype in scope.

You need to include a prototype for each function that you use?

The way you worded this question leads me to believe you may not be aware of
the fact that "#include <stdio.h>" brings a prototype for printf() into
scope. You do not need to manually prototype every standard library function
you call, just include the appropriate header.
 
D

Default User

Sally said:
I am confused as to why the code below does not produce a segmenation
fault. It actually works, and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?


You've learned a valuable lesson, don't rely on your implementation to
catch your mistakes in a predictable way.



Brian Rodenborn
 
J

Joe Laughlin

Kieran said:
Joe Laughlin said:
Mike said:
I am confused as to why the code below does not produce
a segmenation fault.

It's not required to.

It actually works

By (unfortunate) accident. This time.

and I get 12 outputted on my screen. I
would have thought I needed to get memory using malloc?

You do if you want your program's behavior to be
well-defined and predictable, with guarantees from
the language standard about its behavior.

I noticed also if I do use malloc, then free(ptr), I
can still use ptr->z and assign to z successfully?

struct myStruct {
char x[10];
char y[1000];
int z;
};

int main(..) {

struct myStruct *ptr;

ptr->z = 12;
printf("%d",prt->z);

}
You also have another case of undefined behavior:
invocation of 'printf()' with no prototype in scope.

You need to include a prototype for each function that
you use?

The way you worded this question leads me to believe you
may not be aware of the fact that "#include <stdio.h>"
brings a prototype for printf() into scope. You do not
need to manually prototype every standard library
function you call, just include the appropriate header.

Oh, yeah. Nevermind. :)
 
B

Ben Pfaff

Joona I Palaste said:
Yes, you do. In C99 at least. A full definition constitutes a
prototype, however a mere declaration does not always do so.

You are confused. C99 requires called functions to be declared.
It does not require prototypes for called functions. A full
definition may not include a prototype, because it can be a K&R
style definition[1], but it is always a declaration.

[1] C99 has still not outlawed these (which it calls "function
declarators with empty parentheses (not prototype-format
parameter type declarators)"), although they have been obsolete
since C89, and it seems likely that they will be in C0x too.
 
M

Mark McIntyre

Joona I Palaste said:
Yes, you do. In C99 at least. A full definition constitutes a
prototype, however a mere declaration does not always do so.

You are confused. C99 requires called functions to be declared.
It does not require prototypes for called functions. A full
definition may not include a prototype, because it can be a K&R
style definition[1], but it is always a declaration.

ISTR that C99 is a little stricter about when a function call has invoked
UB than C89 was. However I'm not entirely clear about where that is in the
standard.
[1] C99 has still not outlawed these

But its made it pretty darn clear you should not use them (6.11.6 and
6.11.7).
 
B

Ben Pfaff

Mark McIntyre said:
Joona I Palaste said:
Joe Laughlin <[email protected]> scribbled the following:
You need to include a prototype for each function that you use?

Yes, you do. In C99 at least. A full definition constitutes a
prototype, however a mere declaration does not always do so.

You are confused. C99 requires called functions to be declared.
It does not require prototypes for called functions. A full
definition may not include a prototype, because it can be a K&R
style definition[1], but it is always a declaration.

ISTR that C99 is a little stricter about when a function call has invoked
UB than C89 was. However I'm not entirely clear about where that is in the
standard.

You'll have to be specific. I'm not aware of the changes you're
describing, nor do I even vaguely remember something like that.

Both C89 and C99 do require prototypes for variadic functions.
[1] C99 has still not outlawed these

But its made it pretty darn clear you should not use them (6.11.6 and
6.11.7).

That wording is unchanged from C89.
 
M

Mark McIntyre

You'll have to be specific. I'm not aware of the changes you're
describing, nor do I even vaguely remember something like that.

*grin*. I can't be more specific, because I can't remember where it is. I
was kinda hoping someone else would remember. Or disremember and correct
me. Either is acceptable.

(of K&R style)
[1] C99 has still not outlawed these

But its made it pretty darn clear you should not use them (6.11.6 and
6.11.7).

That wording is unchanged from C89.

Sure, and I think that C89 made it perfectly clear that one should not
write that style. Repeating the lesson a decade later reinforces the point,
just don't do it.....
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top