Bus Error asprintf. OS X 10.3.6. gcc 3.3

N

Neil Dunn

Hi,

I don't seem to be able to get asprintf to work when compiling under
OS X.

Using the following code:

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

int main() {

char **w;

asprintf(w,"fooo");

printf("%s\n",*w);

return 0;

}

and compiling using gcc with the -lc and -Wall flags, I get no erros.

The program runs spitting out a Bus Error. The same code on a Linux
machine gcc 3.2.2 compiles and runs as expected.

Any help would be great.

Neil
 
R

Robert Gamble

Hi,

I don't seem to be able to get asprintf to work when compiling under OS
X.

Using the following code:

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

int main() {

char **w;

asprintf(w,"fooo");

printf("%s\n",*w);

return 0;

}

and compiling using gcc with the -lc and -Wall flags, I get no erros.

The program runs spitting out a Bus Error. The same code on a Linux
machine gcc 3.2.2 compiles and runs as expected.

Any help would be great.

Neil

The asprintf function is a GNU/BSD extension (not Standard C) and not
on-topic here. However, there is a fundamental error in your program that
may is undoubtedly the cause of your issue. The prototype for the
asprintf function is:

int asprintf(char **strp, const char *fmt, ...);

Where strp is the address[0] of a pointer to char which the asprintf
function will set to point to a newly allocated string. You are not
passing the address of a pointer to char, you are passing the value of an
uninitialized pointer to pointer to char. The asprintf takes the value at
the address pointed to by the uninitialized w and changes it to point to
the newly allocated string causing undefined behavior. Here is what you
should be doing:

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

int main(void) {

char *w;

asprintf(&w,"fooo");

printf("%s\n",w);

return 0;

}

[0] To be pedantic, this is better articulated as a pointer to pointer to
char and can be written like this:

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

int main(void) {
char *str;
char **w = &str;
asprintf(w,"fooo");
printf("%s\n",*w);
return 0;
}

This is okay because here w has been properly initialized.

<OT>
Don't forget that at least on Linux you also need to #define _GNU_SOURCE
before #include <stdio.h> to access the prototype for asprintf. </OT>

Rob Gamble
 
M

Merrill & Michele

"Robert Gamble:
The asprintf function is a GNU/BSD extension (not Standard C) and not
on-topic here. However, there is a fundamental error in your program that
may is undoubtedly the cause of your issue. The prototype for the
asprintf function is:

int asprintf(char **strp, const char *fmt, ...);
Since this function is OT, might I splice in question, namely, I see how to
PASS crazy looking things like char **tja, but how does one RETURN one of
these funny-looking things?
Where strp is the address[0] of a pointer to char which the asprintf
function will set to point to a newly allocated string. You are not
passing the address of a pointer to char, you are passing the value of an
uninitialized pointer to pointer to char. The asprintf takes the value at
the address pointed to by the uninitialized w and changes it to point to
the newly allocated string causing undefined behavior.

What I want to do is call a function of type I_DONT_KNOW that has ints as
identifiers and return a simple, garden-variety pointer. MPJ
 
R

Robert Gamble

Since this function is OT, might I splice in question, namely, I see how to
PASS crazy looking things like char **tja, but how does one RETURN one of
these funny-looking things?

The same way you return any other type from a function:

char ** myfunc (void) {
char **ptr;

/* Initialize ptr, for example by using malloc */
ptr = NULL;
return ptr;
}
Where strp is the address[0] of a pointer to char which the asprintf
function will set to point to a newly allocated string. You are not
passing the address of a pointer to char, you are passing the value of an
uninitialized pointer to pointer to char. The asprintf takes the value at
the address pointed to by the uninitialized w and changes it to point to
the newly allocated string causing undefined behavior.

What I want to do is call a function of type I_DONT_KNOW that has ints as
identifiers and return a simple, garden-variety pointer. MPJ

I really have no idea what you are asking here, can you clarify? Maybe
you are looking for "void * myfunc (int);" (Really going out on a limb
here).

Rob Gamble
 
M

Merrill & Michele

Robert Gamble said:
Since this function is OT, might I splice in question, namely, I see how to
PASS crazy looking things like char **tja, but how does one RETURN one of
these funny-looking things?

The same way you return any other type from a function:

char ** myfunc (void) {
char **ptr;

/* Initialize ptr, for example by using malloc */
ptr = NULL;
return ptr;
}
Where strp is the address[0] of a pointer to char which the asprintf
function will set to point to a newly allocated string. You are not
passing the address of a pointer to char, you are passing the value of an
uninitialized pointer to pointer to char. The asprintf takes the value at
the address pointed to by the uninitialized w and changes it to point to
the newly allocated string causing undefined behavior.

What I want to do is call a function of type I_DONT_KNOW that has ints as
identifiers and return a simple, garden-variety pointer. MPJ

I really have no idea what you are asking here, can you clarify? Maybe
you are looking for "void * myfunc (int);" (Really going out on a limb
here).
Does such a thing as void * foo(int, int) exist in ANSI C? MPJ
 
R

Robert Gamble

Does such a thing as void * foo(int, int) exist in ANSI C? MPJ

You bet. If you can clearly explain what you are trying to do I might
even give you an example.

Rob Gamble
 
J

Jack Klein

Robert Gamble said:
"Robert Gamble:
Neil Dunn: Hi,

I don't seem to be able to get asprintf to work when compiling under OS
X.

Using the following code:

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

int main() {

char **w;

asprintf(w,"fooo");

printf("%s\n",*w);

return 0;

}

and compiling using gcc with the -lc and -Wall flags, I get no erros.

The program runs spitting out a Bus Error. The same code on a Linux
machine gcc 3.2.2 compiles and runs as expected.

Any help would be great.

The asprintf function is a GNU/BSD extension (not Standard C) and not
on-topic here. However, there is a fundamental error in your program that
may is undoubtedly the cause of your issue. The prototype for the
asprintf function is:

int asprintf(char **strp, const char *fmt, ...);

Since this function is OT, might I splice in question, namely, I see how to
PASS crazy looking things like char **tja, but how does one RETURN one of
these funny-looking things?

The same way you return any other type from a function:

char ** myfunc (void) {
char **ptr;

/* Initialize ptr, for example by using malloc */
ptr = NULL;
return ptr;
}
Where strp is the address[0] of a pointer to char which the asprintf
function will set to point to a newly allocated string. You are not
passing the address of a pointer to char, you are passing the value of an
uninitialized pointer to pointer to char. The asprintf takes the value at
the address pointed to by the uninitialized w and changes it to point to
the newly allocated string causing undefined behavior.

What I want to do is call a function of type I_DONT_KNOW that has ints as
identifiers and return a simple, garden-variety pointer. MPJ

I really have no idea what you are asking here, can you clarify? Maybe
you are looking for "void * myfunc (int);" (Really going out on a limb
here).
Does such a thing as void * foo(int, int) exist in ANSI C? MPJ

Of course. The standard library memory allocation functions malloc(),
calloc(), and realloc() all return a value of type pointer to void.

>
 
M

Merrill & Michele

"Jack Klein:
"Robert Gamble"
int asprintf(char **strp, const char *fmt, ...);
MPJ :
Since this function is OT, might I splice in question, namely, I see how
to
PASS crazy looking things like char **tja, but how does one RETURN
one
of
these funny-looking things?

The same way you return any other type from a function:

char ** myfunc (void) {
char **ptr;

/* Initialize ptr, for example by using malloc */
ptr = NULL;
return ptr;
}

Where strp is the address[0] of a pointer to char which the asprintf
function will set to point to a newly allocated string. You are not
passing the address of a pointer to char, you are passing the value
of
an
uninitialized pointer to pointer to char. The asprintf takes the
value
at
the address pointed to by the uninitialized w and changes it to
point
to
the newly allocated string causing undefined behavior.

What I want to do is call a function of type I_DONT_KNOW that has
ints
as
identifiers and return a simple, garden-variety pointer. MPJ

I really have no idea what you are asking here, can you clarify? Maybe
you are looking for "void * myfunc (int);" (Really going out on a limb
here).
Does such a thing as void * foo(int, int) exist in ANSI C? MPJ

Of course. The standard library memory allocation functions malloc(),
calloc(), and realloc() all return a value of type pointer to void.

Here's where I'm stuck. Comments and questions below.

#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3
static int *increase(int);
int main(void){
int i,buysfor[FAMSIZ];
/*initialize*/
for (i = 0; i < FAMSIZ; ++ i) buysfor = i;
increase(MANGO);
/* to console */
printf(" tja %3d\n", &buysfor[0]);
return 0;
}
static int *increase(int MANGO){
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor = buysfor + MANGO;
return &buysfor[0];
}

This doesn't compile, but, believe it or not, represents a serious effort on
my part to do so. What I'm trying to do is have a function RETURN a pointer
to an int, in this case, the int is the first element of an integer array.
The compiler hangs on the first line of the 'increase' code. Ideas? MPJ
 
R

Robert Gamble

"Jack Klein:
"Robert Gamble"
int asprintf(char **strp, const char *fmt, ...);
MPJ : Since this function is OT, might I splice in question, namely, I see how
to
PASS crazy looking things like char **tja, but how does one RETURN one
of
these funny-looking things?

The same way you return any other type from a function:

char ** myfunc (void) {
char **ptr;

/* Initialize ptr, for example by using malloc */
ptr = NULL;
return ptr;
}

Where strp is the address[0] of a pointer to char which the asprintf
function will set to point to a newly allocated string. You are not
passing the address of a pointer to char, you are passing the value of
an
uninitialized pointer to pointer to char. The asprintf takes the value
at
the address pointed to by the uninitialized w and changes it to point
to
the newly allocated string causing undefined behavior.

What I want to do is call a function of type I_DONT_KNOW that has ints
as
identifiers and return a simple, garden-variety pointer. MPJ

I really have no idea what you are asking here, can you clarify? Maybe
you are looking for "void * myfunc (int);" (Really going out on a limb
here).
Does such a thing as void * foo(int, int) exist in ANSI C? MPJ

Of course. The standard library memory allocation functions malloc(),
calloc(), and realloc() all return a value of type pointer to void.

Here's where I'm stuck. Comments and questions below.

#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3
static int *increase(int);
int main(void){
int i,buysfor[FAMSIZ];
/*initialize*/
for (i = 0; i < FAMSIZ; ++ i) buysfor = i;
increase(MANGO);
/* to console */
printf(" tja %3d\n", &buysfor[0]);
return 0;
}
static int *increase(int MANGO){
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor = buysfor + MANGO;
return &buysfor[0];
}

This doesn't compile, but, believe it or not, represents a serious effort on
my part to do so.


If you are going to post your code and ask someone else to go over it for
you, why don't you take a serious effort to make it semi-readable? You
also need to stop with the inane indentifier names, really it's gotten old
and hinders comprehension. This is what I have after some reformatting:

#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int main(void) {
int i,buysfor[FAMSIZ];
/*initialize*/
for (i = 0; i < FAMSIZ; ++i) buysfor = i;
increase(MANGO);
/* I thought the whole point of this exercise was to be able to
pass a pointer to int back, you aren't even collecting the return
value */
/* to console */
printf(" tja %3d\n", &buysfor[0]);
/* Wrong, you are passing the address of an int, printf is looking
for just an int */
return 0;
}

static int *increase(int MANGO) {
/* This is just so wrong. Remember that just a few lines ago you
defined MANGO to be a macro which expands to 3? Now you are
trying to use it as a variable name? This will expand to (int 3)
which is an error */
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor = buysfor + MANGO;
/* You never declare buysfor here, the buysfor in main is not
visibible from here */
return &buysfor[0];
}
What I'm trying to do is have a function RETURN a pointer
to an int, in this case, the int is the first element of an integer array.
The compiler hangs on the first line of the 'increase' code. Ideas? MPJ

As you can see from my comments, there are numerious things wrong with
your code. Fixing the above issues and making some other modification
based on your implied intentions yields the following:

#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int buysfor[FAMSIZ];

int main(void) {
int i;
int *ptr;
/* initialize */
for (i = 0; i < FAMSIZ; ++i) buysfor = i;
ptr = increase(MANGO);
printf("value returned from increase: %3d\n", *ptr);
return 0;
}

static int *increase(int mango) {
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor += mango;
return &buysfor[0];
}

$ gcc -Wall mmtest.c -o mmtest -ansi -pedantic
$ ./mmtest
value returned from increase: 3
$

If you have any questions about my remarks or the above code, feel free to
ask, but try to be clear and concise.

Rob Gamble
 
M

Merrill & Michele

"Robert Gamble"
If you are going to post your code and ask someone else to go over it for
you, why don't you take a serious effort to make it semi-readable? You
also need to stop with the inane indentifier names, really it's gotten old
and hinders comprehension. This is what I have after some reformatting:

Thank you for your response. I take objection that I don't make serious
efforts to communicate and that the indentifiers are inane. Only MANGO has
no pedigree in my posts, and what would I have called it?
ARBITRARY_IDENTIFIER_
FOR_PEDAGOGICAL_PURPOSES_HAVING_NO_GREAT_SIGNIFICANCE?
#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int main(void) {
int i,buysfor[FAMSIZ];
/*initialize*/
for (i = 0; i < FAMSIZ; ++i) buysfor = i;
increase(MANGO);
/* I thought the whole point of this exercise was to be able to
pass a pointer to int back, you aren't even collecting the return
value */
/* to console */
printf(" tja %3d\n", &buysfor[0]);
/* Wrong, you are passing the address of an int, printf is looking
for just an int */
return 0;
}

static int *increase(int MANGO) {
/* This is just so wrong. Remember that just a few lines ago you
defined MANGO to be a macro which expands to 3? Now you are
trying to use it as a variable name? This will expand to (int 3)
which is an error */
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor = buysfor + MANGO;
/* You never declare buysfor here, the buysfor in main is not
visibible from here */
return &buysfor[0];
}
What I'm trying to do is have a function RETURN a pointer
to an int, in this case, the int is the first element of an integer array.
The compiler hangs on the first line of the 'increase' code. Ideas?


There's at least a couple fatal flaws you've discerned here.
As you can see from my comments, there are numerious things wrong with
your code. Fixing the above issues and making some other modification
based on your implied intentions yields the following:

#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int buysfor[FAMSIZ];

int main(void) {
int i;
int *ptr;
/* initialize */
for (i = 0; i < FAMSIZ; ++i) buysfor = i;
ptr = increase(MANGO);
printf("value returned from increase: %3d\n", *ptr);
return 0;
}

static int *increase(int mango) {
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor += mango;
return &buysfor[0];
}


Your program builds and behaves as I would think, but does it not fall under
the same criticism that buysfor[] would not be visible in the *increase
function call? Does this not fall under the worst type of undefined
behavior, namely, the type that DOESN'T cause Scott Nudds to fly out of your
hard drive?
#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int buysfor[FAMSIZ];

int main(void) {
int i;
int *ptr;
/* initialize */
for (i = 0; i < FAMSIZ; ++i) buysfor = i;
ptr = increase(MANGO);
printf("value returned from increase: %8d\n", ptr);
return 0;
}

static int *increase(int mango) {
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor += mango;
return &buysfor[2];
Furthermore, it was my intention to actually see the address in memory of
some pointer. For that, I'm uncertain what the syntax would be on a printf:
printf("address is %d\n ", ptr); ? MPJ
 
R

Robert Gamble

Thank you for your response. I take objection that I don't make serious
efforts to communicate and that the indentifiers are inane. Only MANGO has
no pedigree in my posts, and what would I have called it?
ARBITRARY_IDENTIFIER_
FOR_PEDAGOGICAL_PURPOSES_HAVING_NO_GREAT_SIGNIFICANCE?

You are free to take objection but if you could reasonably format your
code when you post you will be more likely to receive positive responses.
As far as identifier names, you are notorious for using wildly ungermane
names.
[code snipped]
There's at least a couple fatal flaws you've discerned here.
As you can see from my comments, there are numerious things wrong with
your code. Fixing the above issues and making some other modification
based on your implied intentions yields the following:

#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int buysfor[FAMSIZ];

int main(void) {
int i;
int *ptr;
/* initialize */
for (i = 0; i < FAMSIZ; ++i) buysfor = i;
ptr = increase(MANGO);
printf("value returned from increase: %3d\n", *ptr);
return 0;
}

static int *increase(int mango) {
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor += mango;
return &buysfor[0];
}


Your program builds and behaves as I would think, but does it not fall under
the same criticism that buysfor[] would not be visible in the *increase
function call? Does this not fall under the worst type of undefined
behavior, namely, the type that DOESN'T cause Scott Nudds to fly out of your
hard drive?


Um...no. Notice that I declared buysfor outside of a function definition
or block. The scope for buysfor is until the end of the translation unit
(file scope).
#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int buysfor[FAMSIZ];

int main(void) {
int i;
int *ptr;
/* initialize */
for (i = 0; i < FAMSIZ; ++i) buysfor = i;
ptr = increase(MANGO);
printf("value returned from increase: %8d\n", ptr);
return 0;
}

static int *increase(int mango) {
int i;
for (i = 0; i < FAMSIZ; ++ i) buysfor += mango;
return &buysfor[2];
Furthermore, it was my intention to actually see the address in memory of
some pointer. For that, I'm uncertain what the syntax would be on a printf:
printf("address is %d\n ", ptr); ? MPJ


printf("address is %p\n",(void *)ptr);

Rob Gamble
 
M

Merrill & Michele

"Robert Gamble"
MPJ:
As you can see from my comments, there are numerious things wrong with
your code. Fixing the above issues and making some other modification
based on your implied intentions yields the following:

#include <stdio.h>
#define FAMSIZ 7
#define MANGO 3

static int *increase(int);

int buysfor[FAMSIZ];

I missed that this declaration was at file scope.
Um...no. Notice that I declared buysfor outside of a function definition
or block. The scope for buysfor is until the end of the translation unit
(file scope).
printf("address is %p\n",(void *)ptr);

I can well understand if you've had enough of this problem. This printf
certainly works and table B-1 shows that the character p after % means that
the compiler's looking for a void *. Doesn't it seem like ptr is already a
pointer and that therefore void * ptr would be a creature of type void ** ?
MPJ
 
R

Robert Gamble

"Robert Gamble" [snip]
printf("address is %p\n",(void *)ptr);

I can well understand if you've had enough of this problem. This printf
certainly works and table B-1 shows that the character p after % means that
the compiler's looking for a void *. Doesn't it seem like ptr is already a
pointer and that therefore void * ptr would be a creature of type void ** ?
MPJ

No.

Robert Gamble
 

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
474,154
Messages
2,570,870
Members
47,400
Latest member
FloridaFvt

Latest Threads

Top