I am wondering what am I doing wrong here? I cast the void pointer into a struct buffer and it only prints out garbage. Shouldn't buffer now point to ptr that is a pointer back to the original buffer that we allocated memory for?
#include <stdio.h>
#include <pthread.h>
struct buffer{
int a;
char *string[];
}buffer;
void thread1_function(void *ptr){
struct buffer *buffer=(struct buffer*)ptr;
printf("hello world\n");
printf("%s-%n\n", buffer->string,buffer->a);
}
int main(){
struct buffer *buffer;
int err;
buffer = (struct buffer*)malloc((11*sizeof(char))+sizeof(int));
pthread_t thread1;
sprintf(buffer->string,"%s","strint");
buffer->a=1;
printf("main: %s - %d\n",buffer->string,buffer->a);
err = pthread_create(&thread1, NULL, thread1_function, &buffer);
printf("error: %d\n",err);
pthread_join(thread1,NULL);
return 0;
}
~
You pass the pointer to the pointer to the struct to your thread. Try passing the pointer to the struct instead. ;)
err = pthread_create(&thread1, NULL, thread1_function, &buffer);
becomes
err = pthread_create(&thread1, NULL, thread1_function, buffer);
EDIT:
Found another mistake: printf("...%n")
in the thread function. %n
indicates to store the number written so far into the position, the int*
parameter at that position points to. You obviously mean %d
there, as in your main()
.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7fe3b70 (LWP 24311)]
0x0018f5c9 in _IO_vfprintf_internal (s=0x1, format=<optimized out>, ap=0xb7fe337c "$\200\001") at vfprintf.c:1622
1622 vfprintf.c: No such file or directory.
in vfprintf.c
(gdb)
< - Craig Sparks 2012-04-04 07:36
The string
member of the struct is defined as a "flexible" array of char *
pointers. You seem to treat it as an array of chars instead, by allocating 11 * sizeof(char)
bytes for it and then copying a string to it.
I think the intended layout of your structure should be as follows:
struct buffer {
int a;
char string[];
} buffer;
And then allocate it as:
buffer = malloc(sizeof(struct buffer) + SIZE_OF_STRING);
sizeof struct buffer
or similar to allocate enough memory - moooeeeep 2012-04-04 07:29
Program received signal SIGSEGV, Segmentation fault. 0x0804857e in main ( - Craig Sparks 2012-04-04 07:31
In addition to the notes the others have already provided:
string
s bounds.sizeof(struct buffer)
(or simply create a struct buffer
on the stack) to make sure that enough memory is allocated (there may be padding issues). You may also need to allocate memory for and properly initialize the character array and the pointer to it (string
) of course.&thread1_function
, i.e. a function pointer. Also, thread1_function()
needs to return void*
, instead of void
.buffer
(one in global scope, and one inside function main()
)? How are you sure which one you pass to the thread anyway?After all, there are that many issues with that code, that I'm not surprised that it still fails after you've fixed one error. (Actually I'm surprised that it did compile.)
Here's some fixed code: There were a lot of warnings on first compiling the code. You should not ignore warnings. Even though your code did compile, warnings are often valuable information to track down errors, especially notable when the program fails. As in your case. In the first place you should not care about the garbage that is printed, but about the warnings the compiler throws at you!
(If you want more warnings try passing -Wall -Wextra -pedantic
to your gcc
of choice.)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct buffer{
int a;
char string[10];
};
void* thread1_function(void *ptr){
struct buffer *buffer=(struct buffer*)ptr;
printf("hello world\n");
printf("%s-%d\n", buffer->string,buffer->a);
return NULL;
}
int main(){
int err;
pthread_t thread1;
struct buffer *buffer;
buffer = (struct buffer*)malloc(sizeof (struct buffer) );
buffer->a=1;
snprintf(buffer->string, sizeof buffer->string, "%s", "strint");
printf("main: %s - %d\n", buffer->string, buffer->a);
err = pthread_create(&thread1, NULL, &thread1_function, buffer);
printf("error: %d\n", err);
pthread_join(thread1, NULL);
return 0;
}
asprintf
- user1252434 2012-04-04 07:56
threadFunc
and &threadFunc
are equivalent, both evaluate to the pointer to the function. Adding the ampersand makes the pointer nature of the expression more obvious to a reader of the source code, so I'd prefer to add it - user1252434 2012-04-04 08:21