sprintf leading up to bus error (signal 10)

S

steve

Well I've been working all morning and have finally found the source of
my "bus error (signal 10)" errors. The source is odd. The error
occurs in any function where I make the function call:

(void)sprintf(ptr_testing, "This is my string");

This in itself isn't where the actual error occurs. The error occurs
at any later point, in the same function where the sprintf() call is
made, where I try to assign a value to one of the variables in one of
my data structures. The lines are syntactically reminiscent of:

((lst_vals *)userInst->seniorData)->lst_T_chan = (double) 340.0;

Where the seniorData is a pointer to a lst_vals data structure defined
as follows:

/*data structure for seniorData to point to*/
typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

Any ideas on what's going on? It's way beyond me. I orginally thought
that it was a simple typecasting problem, I'm pretty sure I'm wrong.
It's extremely odd because any number of commands between those two
lines of code will be executed. The instant the assignment shown above
is reached the program exits with signal 10.

Thanks in advance,

Steve
 
A

Alexei A. Frounze

steve said:
Well I've been working all morning and have finally found the source of
my "bus error (signal 10)" errors. The source is odd. The error
occurs in any function where I make the function call:

(void)sprintf(ptr_testing, "This is my string");

This in itself isn't where the actual error occurs. The error occurs
at any later point, in the same function where the sprintf() call is
made, where I try to assign a value to one of the variables in one of
my data structures. The lines are syntactically reminiscent of:

((lst_vals *)userInst->seniorData)->lst_T_chan = (double) 340.0;

IMO, (double) isn't necessary as the floating point constants are double by
default.
Where the seniorData is a pointer to a lst_vals data structure defined
as follows:

/*data structure for seniorData to point to*/
typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

Any ideas on what's going on? It's way beyond me. I orginally thought
that it was a simple typecasting problem, I'm pretty sure I'm wrong.
It's extremely odd because any number of commands between those two
lines of code will be executed. The instant the assignment shown above
is reached the program exits with signal 10.

Are you sure there's enough memory for a structure of type lst_vals at the
address to which points userInst->seniorData? I don't know what exactly
you're doing but this pointer cast makes me suspect that this is the case.
I'd expect a segmentation fault here, however, but you never know what you
break by writing where you shouldn't.

Alex
 
G

Gordon Burditt

Well I've been working all morning and have finally found the source of
my "bus error (signal 10)" errors. The source is odd. The error
occurs in any function where I make the function call:

(void)sprintf(ptr_testing, "This is my string");

So where does ptr_testing point? How was that memory allocated?
Are you sure there is enough memory allocated to fit that string?
This in itself isn't where the actual error occurs. The error occurs
at any later point, in the same function where the sprintf() call is
made, where I try to assign a value to one of the variables in one of
my data structures.

Possible problem: the sprintf() above stomps memory.
The line below tries to use a pointer stored in stomped memory.
KABOOM!!
The lines are syntactically reminiscent of:

((lst_vals *)userInst->seniorData)->lst_T_chan = (double) 340.0;

Where the seniorData is a pointer to a lst_vals data structure defined
as follows:

/*data structure for seniorData to point to*/
typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

Any ideas on what's going on? It's way beyond me. I orginally thought
that it was a simple typecasting problem, I'm pretty sure I'm wrong.
It's extremely odd because any number of commands between those two
lines of code will be executed.

This is often a sign of a problem with buffer overrun, use of uninitialized
pointers, memory stomping, etc.

Gordon L. Burditt
 
S

steve

I should've given a warning that I'm not a software guy but really an
electronics engineer so this is somewhat untested ground for me

ptr_testing is defined as:

char *ptr_testing;

So I've not explicitly allocated any memory. But I've also tried
using:

char ptr_testing[255];

Which still does not work.

I suspected it had something to do with the sprintf() function
overwritting something that I needed and then later this thing was
being used, or attempted it's use before failing catasptrophically.

I'm sure it's something fundamental that I'm over looking.

Again, thanks for your help,

Steve
 
M

Michael Mair

steve said:
Well I've been working all morning and have finally found the source of
my "bus error (signal 10)" errors. The source is odd. The error
occurs in any function where I make the function call:

(void)sprintf(ptr_testing, "This is my string");

This in itself isn't where the actual error occurs. The error occurs
at any later point, in the same function where the sprintf() call is
made, where I try to assign a value to one of the variables in one of
my data structures. The lines are syntactically reminiscent of:

((lst_vals *)userInst->seniorData)->lst_T_chan = (double) 340.0;

Where the seniorData is a pointer to a lst_vals data structure defined
as follows:

/*data structure for seniorData to point to*/
typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

Any ideas on what's going on? It's way beyond me. I orginally thought
that it was a simple typecasting problem, I'm pretty sure I'm wrong.
It's extremely odd because any number of commands between those two
lines of code will be executed. The instant the assignment shown above
is reached the program exits with signal 10.

SIGBUS/bus error often indicates an alignment problem; i.e. it is
possible that userList->seniorData is not suitable to be cast to
(lst_vals *) because lst_vals has stricter alignment requirements than
the type userList->seniorData points to, e.g. 8 byte vs. 4 byte.
It may be that you get unlucky/lucky dependent on the sprintf() --
the true error is probably somewhere else.

However, bus errors have nothing to do with standard C and are not
on-topic here. So, you can either go to an os-/compiler-specific
newsgroup or reduce your code to a minimal example exhibiting the
noxious behaviour and show it to comp.lang.c.

Cheers
Michael
 
S

steve

I should've given a warning that I'm not a software guy but really an
electronics engineer so this is somewhat untested ground for me, but
I'm doing my best.
IMO, (double) isn't necessary as the floating point constants are double by
default.

You're right the double type cast is not required but in one of my many
attempts to resolve the problem I started typecasting everything. This
is infact an artifact of previous attemps, but removing it doesn't
solve the problem, unfortunately.
Are you sure there's enough memory for a structure of type lst_vals at the
address to which points userInst->seniorData? I don't know what exactly
you're doing but this pointer cast makes me suspect that this is the case.
I'd expect a segmentation fault here, however, but you never know what you
break by writing where you shouldn't.

There should be enough room for the structure as I'm performing a
malloc as follows:

if(!malloc(sizeof(lst_vals))){
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)lst_ptr;

which is returning true.

Any other ideas?

Again, thanks for your help,

Steve
 
S

steve

Your answer seems like its on target but it's a little over my head.
Not a programmer from birth here but merely out of necessity. Just
when I think I'm starting to understand the language someone opens a
whole new can of worms.

userList->seniorData is a void pointer in it definition as a structure.
I wasn't aware that there were alignment requirements period. Could
you possibly do me a favour and elaborate on that or point (no pun
intended) me to a source that you think offers a decent explanation?

How could I find out what size the pointer should point to? I have a
series of header files with several definitions, structures, and
function headers that are automatically generated by the circuit
simulator I am using. My job is merely to write the math and such that
defines the circuit I'm trying to model in various predefined
functions. Would there be some clues in the structure definition of
userInst itself?

typedef struct _UserInstDef UserInstDef;
struct _UserInstDef
{
char *tag; /* instance name */
UserElemDef *userDef; /* access to user-element definition */
SENIOR_USER_DATA *pData; /* instance's parameters */
void *eeElemInst; /* EEsof's element instance */
void *eeDevInst; /* EEsof's nonlinear device instance */
void *seniorData; /* data allocated/managed/used only by Senior
module (arbitrary) */
};

I appologize if this is off topic. I just assumed since I was writting
C and I got the error from C that it belonged here. I was unaware that
the problems would be os specific.

Thanks for your post,

Steve
 
O

Old Wolf

steve said:
I should've given a warning that I'm not a software guy but really an
electronics engineer so this is somewhat untested ground for me

ptr_testing is defined as:

char *ptr_testing;

So I've not explicitly allocated any memory.

So where abouts in memory do you think your sprintf is going
to write to? The Boston Tea Party?
But I've also tried using:

char ptr_testing[255];

Which still does not work.

So now you've fixed one bug (assuming you never write more than
255 chars to it!). There may still be more bugs to fix than this
one.
I'm sure it's something fundamental that I'm over looking.

Unless you can post a complete program that demonstrates the
problem, we're all just guessing really. What compiler are you
using? Perhaps you can run a memory-checker program that will
tell you when you are writing to memory you shouldn't be.
 
S

steve

Again I'd like to reitterate: I should've given a warning that I'm not
a software guy but really an electronics engineer so this is somewhat
untested ground for me
So where abouts in memory do you think your sprintf is going
to write to? The Boston Tea Party?

I actually thought that the sprintf would write to a printer and then
save the page to be scanned when the string was required.

All joking aside, I'm not stupid and don't terribly enjoy being moked
(If the boston tea party comment was meant as a joke then I appologize
for having taken it as condescendence). Like I said I'm new to this
and doing my best. My "solution" of allocating space for 255
characters is an adequate one because the strings that I'll be dealing
with are significantly shorter than 255 characters.

If a complete program is required than I'll gladly provide what I can,
but again I ask that you keep in mind I'm relatively new by comparison
to the people who typically post to newsgroups like this. If you feel
my problem is below you then you're welcome to move on although I'll
miss out on the help, which is unfortunate.

As for code:

typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

struct _UserInstDef
{
/*several elements removed for space's sake*/
void *seniorData; /* data allocated/managed/used only by Senior
module (arbitrary) */
};

static boolean pre_analysis (
UserInstDef *userInst)
{
boolean status = TRUE;
lst_vals *lst_ptr;

char ptr_test[255];
(void)sprintf(ptr_test,"testing");
send_info_to_scn(ptr_test);

if(!malloc(sizeof(lst_vals))){
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)lst_ptr;

/*Initialize*/
((lst_vals *)userInst->seniorData)->lst_T_chan = 340.0;

END:
return status;
}/*pre_analysis()*/

Other than what is shown above the remainder of the code is beyond me
as it is generated by the software I am using and its inner workings
are "transparent" to the user. If there are specifics I can probably
dig them out of the documentation and post.

Again, thank you for any help that can be provided,
 
M

Michael Mair

steve said:
Your answer seems like its on target but it's a little over my head.
Not a programmer from birth here but merely out of necessity. Just
when I think I'm starting to understand the language someone opens a
whole new can of worms.

userList->seniorData is a void pointer in it definition as a structure.
I wasn't aware that there were alignment requirements period. Could
you possibly do me a favour and elaborate on that or point (no pun
intended) me to a source that you think offers a decent explanation?

How could I find out what size the pointer should point to? I have a
series of header files with several definitions, structures, and
function headers that are automatically generated by the circuit
simulator I am using. My job is merely to write the math and such that
defines the circuit I'm trying to model in various predefined
functions. Would there be some clues in the structure definition of
userInst itself?

typedef struct _UserInstDef UserInstDef;
struct _UserInstDef
{
char *tag; /* instance name */
UserElemDef *userDef; /* access to user-element definition */
SENIOR_USER_DATA *pData; /* instance's parameters */
void *eeElemInst; /* EEsof's element instance */
void *eeDevInst; /* EEsof's nonlinear device instance */
void *seniorData; /* data allocated/managed/used only by Senior
module (arbitrary) */
};

I appologize if this is off topic. I just assumed since I was writting
C and I got the error from C that it belonged here. I was unaware that
the problems would be os specific.

Please always provide a minimum of context -- it is possible that
your answer makes it to some server faster than my original response
(or that mine does not make it at all).

void *: void * is -- as you probably know -- kind of a generic pointer
type, i.e. for every type T; T t, T* pT, void *p the following always
works: pT = &t, p = pT, pT = p where pT now again == &t.
Alignment: A numeric type (integer or floating point) may be restricted
in the places in memory where it can "start"; often, this means that
the location in memory has remainder zero when divided by the size (or
a divisor of the size) of the type (size means the return value of
sizeof), i.e. it is 2-aligned, 4-aligned etc.
A structure usually meets the alignment requirements of the member
with the strictest alignment requirements. If, for example, double
is of size 8 and 8-aligned, a structure containing a double probably
also is 8-aligned, has (due to padding bytes between members) a size
which is a multiple of 8 and so on. If you would memmove() the structure
by one, two, ..., seven bytes, the alignment would no longer fit.
How do we get suitably aligned storage: Automatic/static variables are
suitably aligned. Allocated storage returned by malloc() is suitably
aligned for every possible alignment requirement.
So, if seniorData is assigned the return value of a malloc() call
allocating enough storage (and not returning NULL), then saying
pT = seniorData works.
If you, however, change seniorData (increment it by the size of, say,
another type), you may be in trouble.

It is also possible that your sprintf() call overwrites seniorData,
effectively yielding an invalid address but for some reason you die
with bus error rather than segmentation fault (see also the other
responses).

Try to get together a running minimal example for us so we can
help you without straining our crystal balls...


Cheers
Michael
 
F

Flash Gordon

steve said:
I should've given a warning that I'm not a software guy but really an
electronics engineer so this is somewhat untested ground for me, but
I'm doing my best.

I suggest you buy a copy of K&R2 and read the FAQ for this group (google
will find the FAQ which tells you what K&R2 is and lots of other good
stuff).
You're right the double type cast is not required but in one of my many
attempts to resolve the problem I started typecasting everything. This
is infact an artifact of previous attemps, but removing it doesn't
solve the problem, unfortunately.

I would suggest you strip out all the casts. There are a few instances
where casts are needed, but generally they are not and just hide problems.
There should be enough room for the structure as I'm performing a
malloc as follows:

if(!malloc(sizeof(lst_vals))){

If this is your actual code it is wrong. You need to assign the pointer
value returned by malloc to the pointer you want to point to it. Also, a
good way (in general) to do your mallocs and avoid allocating the wrong
amount of memory is:
ptr = malloc(N * sizeof *ptr);
if (ptr) {
/* Handle error */

Where N is the number of items you want space for. This way, you are
effectively telling the compiler you want space for N of the things ptr
points to.
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)lst_ptr;

which is returning true.

Any other ideas?

Try stripping things out of the code to produce a small, complete,
compilable and runable program that shows the problem. You might find
the error yourself in cutting the program down but, if not, by allowing
us to see a complete program exhibiting the problem you allow us to see
the actual error. Otherwise, the problem could be with any of the things
you have not posted.
 
S

steve

Please always provide a minimum of context -- it is possible that
your answer makes it to some server faster than my original response
(or that mine does not make it at all).

I will remember this for future posts. This is however somewhat
difficult for me as I'm not writting a program so much as filling in
the blanks of a lot of automatically generated code. For example I
can't even touch header files as they are automatically recreated when
the code is about to be compiled. A better description of what I'm
doing is writting a model in c for ADS (an electronics circuit
simulator) and as a results I don't think I have what most people would
call working knowledge of C, well at the full program level. Instead
I'm work inside a "comfortable" shell where a lot of stuff is taken
care of for, a.k.a. hidden from, me.
void *: void * is -- as you probably know -- kind of a generic pointer
type, i.e. for every type T; T t, T* pT, void *p the following always
works: pT = &t, p = pT, pT = p where pT now again == &t.

This is what I had thought was the case, so I'm still on the same page.
Alignment: A numeric type (integer or floating point) may be restricted
in the places in memory where it can "start"; often, this means that
the location in memory has remainder zero when divided by the size (or
a divisor of the size) of the type (size means the return value of
sizeof), i.e. it is 2-aligned, 4-aligned etc.
A structure usually meets the alignment requirements of the member
with the strictest alignment requirements. If, for example, double
is of size 8 and 8-aligned, a structure containing a double probably
also is 8-aligned, has (due to padding bytes between members) a size
which is a multiple of 8 and so on. If you would memmove() the structure
by one, two, ..., seven bytes, the alignment would no longer fit.
How do we get suitably aligned storage: Automatic/static variables are
suitably aligned. Allocated storage returned by malloc() is suitably
aligned for every possible alignment requirement.
So, if seniorData is assigned the return value of a malloc() call
allocating enough storage (and not returning NULL), then saying
pT = seniorData works.
If you, however, change seniorData (increment it by the size of, say,
another type), you may be in trouble.

This is all new to me but I've taken some courses in assembly and the
like and it makes sense when you point it out. So this I follow...now.
(Thank you for the explanation...greatly needed)
It is also possible that your sprintf() call overwrites seniorData,
effectively yielding an invalid address but for some reason you die
with bus error rather than segmentation fault (see also the other
responses).

This I wouldn't have thought to be possible, but if you say it is I
have faith in you. From an assembly point of view it makes sense.
From a "why would it let you do something like that point of view" it
just seems wrong, although I'm sure it has it's applications.

Having considered this from previous posts I was under the impression
that the malloc() that I was performing, which I only mentioned after
the responce you've sent (your comment about providing a minimalistic
example is making more and more sence), to allow space for my data
structure would prevent such and overwrite from happening. However, as
everyone seems to pretty much be in agreement, this is more than likely
the case. I'll so some more reading and see if I can sort this one
out.
Try to get together a running minimal example for us so we can
help you without straining our crystal balls...

Thank you very much for all of the help, explanations and patience. It
is very much needed.

Thanks again,

Steve
 
C

CBFalconer

steve said:
Well I've been working all morning and have finally found the
source of my "bus error (signal 10)" errors. The source is odd.
The error occurs in any function where I make the function call:

(void)sprintf(ptr_testing, "This is my string");
.... snip ...

Any ideas on what's going on? It's way beyond me. I orginally
thought that it was a simple typecasting problem, I'm pretty sure
I'm wrong. It's extremely odd because any number of commands
between those two lines of code will be executed. The instant
the assignment shown above is reached the program exits with
signal 10.

Our crystal balls are on strike. Cut the whole thing down to a
_compilable_ complete program and post that, together with input
and output, and we may then be able to help. Of course, by that
time you may have found the problem all by yourself.
 
C

CBFalconer

steve said:
.... snip ...

If a complete program is required than I'll gladly provide what I can,
but again I ask that you keep in mind I'm relatively new by comparison
to the people who typically post to newsgroups like this. If you feel
my problem is below you then you're welcome to move on although I'll
miss out on the help, which is unfortunate.

What is really required for adequate help is a complete, compilable
program that exhibits the problem. However there is at least one
obvious thing below:
As for code:

typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

struct _UserInstDef
{
/*several elements removed for space's sake*/
void *seniorData; /* data allocated/managed/used only by Senior
module (arbitrary) */
};

static boolean pre_analysis (
UserInstDef *userInst)
{
boolean status = TRUE;
lst_vals *lst_ptr;

char ptr_test[255];
(void)sprintf(ptr_test,"testing");
send_info_to_scn(ptr_test);

if(!malloc(sizeof(lst_vals))){

if (!(lst_ptr = malloc(sizeof *lst_ptr)) {
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)lst_ptr;

/*Initialize*/
((lst_vals *)userInst->seniorData)->lst_T_chan = 340.0;

END:
return status;
}/*pre_analysis()*/

Other than what is shown above the remainder of the code is beyond me
as it is generated by the software I am using and its inner workings
are "transparent" to the user. If there are specifics I can probably
dig them out of the documentation and post.

Again, thank you for any help that can be provided,

And get rid of those silly casts. Most casts serve only to hide
programmer errors. Using the macro TRUE is always suspect, and so
is the presence of a boolean type.
 
M

Michael Mair

CBFalconer said:
steve wrote:

... snip ...
[snip]
static boolean pre_analysis (
UserInstDef *userInst)
{
boolean status = TRUE;
lst_vals *lst_ptr;

char ptr_test[255];
(void)sprintf(ptr_test,"testing");
send_info_to_scn(ptr_test);

if(!malloc(sizeof(lst_vals))){

if (!(lst_ptr = malloc(sizeof *lst_ptr)) {

send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)lst_ptr;

/*Initialize*/
((lst_vals *)userInst->seniorData)->lst_T_chan = 340.0;

END:
return status;
}/*pre_analysis()*/

Other than what is shown above the remainder of the code is beyond me
as it is generated by the software I am using and its inner workings
are "transparent" to the user. If there are specifics I can probably
dig them out of the documentation and post.

Again, thank you for any help that can be provided,

And get rid of those silly casts. Most casts serve only to hide
programmer errors. Using the macro TRUE is always suspect, and so
is the presence of a boolean type.

The OP indicated that part of the C code is generated.
Depending on the quality of the code generator, there may not
be much opportunity/many hooks to customise code generation.
So, he may well be stuck with the generators best shot at a
boolean type (or the generator may support platform specific
one-bit-types).
<OT>
There _are_ nearly fully customisable production code generators
(claiming some degree of or fully ANSI C conforming output) for
example in the Simulink/Stateflow-to-C area but they are not
exactly inexpensive; however, in the wrong hands, e.g. of some
C newbie, the most powerful tool cannot help much.
</OT>
As for the casts: Casting seniorData is necessary, casting
the return value of sprintf() to void may be seen as a
deliberate act of documenting that this value is discarded
(maybe in this case a bad idea as this value may help finding
a potential overflow), so the only "silly" cast is the one
in front of lst_ptr (to void *).

Cheers
Michael
 
S

steve

CBFalconer,

When you said I might sort it out myself you were right. My problem
was in my allocation of space, which was being done for a pointer to my
data structure and not actually allocating space for the structure
itself.

Thus:

typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

static boolean pre_analysis (
UserInstDef *userInst)
{
boolean status = TRUE;
lst_vals lst_ptr;
boolean allocated = malloc(sizeof(lst_vals));

char ptr_test[20];

(void)sprintf(ptr_test,"testing");
send_info_to_scn(ptr_test);

if(!allocated){
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)&lst_ptr;

/*Initialize*/
((lst_vals *)userInst->seniorData)->lst_T_chan = 340.0;
((lst_vals *)userInst->seniorData)->current_T_chan = 340;
((lst_vals *)userInst->seniorData)->lst_t = 0;
((lst_vals *)userInst->seniorData)->current_t = 0;

END:
return status;
}/*pre_analysis()*/

Works.

Thank you all so much for your help.
Next time I'll post the workable code right away.

PS. the google groups -> reply technique has been noted and will be
heeded.

Thanks again,

Steve
 
K

Kenneth Brody

steve said:
Well I've been working all morning and have finally found the source of
my "bus error (signal 10)" errors. The source is odd. The error
occurs in any function where I make the function call:

(void)sprintf(ptr_testing, "This is my string");

This in itself isn't where the actual error occurs. The error occurs
at any later point, in the same function where the sprintf() call is
made, where I try to assign a value to one of the variables in one of
my data structures. The lines are syntactically reminiscent of:

((lst_vals *)userInst->seniorData)->lst_T_chan = (double) 340.0;
[...]

How is ptr_testing defined? Is it large enough to hold the string?
If not, you will be overwriting memory, causing undefined behavior.
For example, it may overwrite part of memory pointed to be userInst,
causing "((lst_vals *)userInst->seniorData)->lst_T_chan" to no longer
be properly aligned to hold a double. (Misaligned pointers are the
typical cause of "bus error" on Unix systems.)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Kenneth Brody

steve wrote:
[...]
typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

static boolean pre_analysis (
UserInstDef *userInst)
{
boolean status = TRUE;
lst_vals lst_ptr;
boolean allocated = malloc(sizeof(lst_vals));

You are allocating memory, and then convert the pointer (if you're
not getting a warning/error about converting a pointer to integer,
you're missing some headers) to a boolean. This is meaningless,
and you have now lost the pointer, causing a memory leak.
From the code, I assume you probably want something like:

lst_ptr = malloc(sizeof(lst_ptr));

(And change the "!allocated" test below to "lst_ptr != NULL".)

However, see below about hanging pointers.
char ptr_test[20];

(void)sprintf(ptr_test,"testing");
send_info_to_scn(ptr_test);

if(!allocated){
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)&lst_ptr;

Note that lst_ptr no longer exists onse pre_analysis() returns.
Therefore, userInst->seniorData is left with an invalid pointer.
/*Initialize*/
((lst_vals *)userInst->seniorData)->lst_T_chan = 340.0;
((lst_vals *)userInst->seniorData)->current_T_chan = 340;
((lst_vals *)userInst->seniorData)->lst_t = 0;
((lst_vals *)userInst->seniorData)->current_t = 0;

Why not just use:

lst_ptr.lst_T_chan = 340.0;
lst_ptr.curent_T_chan = 340;
lst_ptr.lst_t = 0;
lst_ptr.current_t = 0;

It's the same net result, and makes much more sense when reading it.
(Though you still have the hanging pointer issue.)
END:
return status;
}/*pre_analysis()*/

Works.

It won't work if you try to dereference useInst->seniorData from
the calling routine.

[...]

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
S

steve

Kenneth said:
steve wrote:
[...]
typedef struct {
double lst_T_chan, current_T_chan, lst_t, current_t;
} lst_vals;

static boolean pre_analysis (
UserInstDef *userInst)
{
boolean status = TRUE;
lst_vals lst_ptr;
boolean allocated = malloc(sizeof(lst_vals));

You are allocating memory, and then convert the pointer (if you're
not getting a warning/error about converting a pointer to integer,
you're missing some headers) to a boolean. This is meaningless,
and you have now lost the pointer, causing a memory leak.
From the code, I assume you probably want something like:

lst_ptr = malloc(sizeof(lst_ptr));
My appologies, I realized to boolean error not long after submitting
the new code and have since changed to something along the lines of:

userInst->seniorData = (void *)malloc(sizeof(lst_vals));

This should still allow userInst->seniorData to point to one data
structure of type lst_vals should it not? My understanding is that
allocated space stayed allocated until free() was used to free it
(which I do from another function).
(And change the "!allocated" test below to "lst_ptr != NULL".) This has been corrected.

However, see below about hanging pointers.
char ptr_test[20];

(void)sprintf(ptr_test,"testing");
send_info_to_scn(ptr_test);

if(!allocated){
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;
}

userInst->seniorData = (void *)&lst_ptr;

Note that lst_ptr no longer exists onse pre_analysis() returns.
Therefore, userInst->seniorData is left with an invalid pointer.
/*Initialize*/
((lst_vals *)userInst->seniorData)->lst_T_chan = 340.0;
((lst_vals *)userInst->seniorData)->current_T_chan = 340;
((lst_vals *)userInst->seniorData)->lst_t = 0;
((lst_vals *)userInst->seniorData)->current_t = 0;

Why not just use:

lst_ptr.lst_T_chan = 340.0;
lst_ptr.curent_T_chan = 340;
lst_ptr.lst_t = 0;
lst_ptr.current_t = 0;

It's the same net result, and makes much more sense when reading it.
(Though you still have the hanging pointer issue.)
I'm fairly certain this won't work because I'm trying to get the data
structure of type lst_vals out of this function so that it can be used
by other parts of the entire program. See below for "new" code, which
again seems to work. The only failing will be if the OS or whomever is
responsible for it frees up the memory on me when it leaves the
function (which I hope is not the case, please let me know either way).
It won't work if you try to dereference useInst->seniorData from
the calling routine.
static boolean pre_analysis (
UserInstDef *userInst)
{
boolean status = TRUE;
char ptr_testing[20];

(void)sprintf(ptr_testing,"testing");
send_info_to_scn(ptr_testing);

/*allocate space and verify allocated space*/
userInst->seniorData = (void *)malloc(sizeof(lst_vals));
if(userInst->seniorData == NULL){
send_error_to_scn("Error allocating memory in pre_analysis");
status = FALSE;
goto END;}

/*Initialize*/
((lst_vals *)userInst->seniorData)->lst_T_chan = 340.0;
((lst_vals *)userInst->seniorData)->current_T_chan = 340;
((lst_vals *)userInst->seniorData)->lst_t = 0;
((lst_vals *)userInst->seniorData)->current_t = 0;

END:
return status;
}/*pre_analysis()*/
 
S

steve

Kenneth said:
steve said:
Well I've been working all morning and have finally found the source of
my "bus error (signal 10)" errors. The source is odd. The error
occurs in any function where I make the function call:

(void)sprintf(ptr_testing, "This is my string");

This in itself isn't where the actual error occurs. The error occurs
at any later point, in the same function where the sprintf() call is
made, where I try to assign a value to one of the variables in one of
my data structures. The lines are syntactically reminiscent of:

((lst_vals *)userInst->seniorData)->lst_T_chan = (double) 340.0;
[...]

How is ptr_testing defined? Is it large enough to hold the string?
If not, you will be overwriting memory, causing undefined behavior.
For example, it may overwrite part of memory pointed to be userInst,
causing "((lst_vals *)userInst->seniorData)->lst_T_chan" to no longer
be properly aligned to hold a double. (Misaligned pointers are the
typical cause of "bus error" on Unix systems.)
ptr_testing is defined as an array of 20 characters and is always being
filled with less than this when I make calls to sprintf(). You are
correct, I'm working on a unix system, which I no doubt should've said
up front.

Next time I start a new thread it will have all of this stuff in it.
My appologies.

Thanks again for the help,

Steve
 

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,586
Members
45,084
Latest member
HansGeorgi

Latest Threads

Top