我有一个动态分配的结构数组,' buff'。每个元素都是一个结构,它有一些整数变量和一个指针" buffer_ptr'它指向另一个动态分配的结构数组。两个数组的大小都是命令行输入。
int buffer_size;
int user_num;
struct tuple
{
char userID[5];
char topic[16];
int weight;
};
struct buff_ctrl
{
struct tuple* buffer_ptr;
int in;
int out;
int numItems;
int done;
};
在main()中创建并初始化数组,如下所示:
int main(int argc, char* argv[])
{
void *status;
pthread_t mapThd;
if(argc != 4)
{
printf("Input format: ./combiner <buffer_size> <number_of_users> <input_file>\n");
return -1;
}
buffer_size = atoi(argv[1]);
user_num = atoi(argv[2]);
struct buff_ctrl *buff = (struct buff_ctrl*)malloc(user_num * sizeof(struct buff_ctrl));
for(int i=0; i<user_num; i++)
{
struct buff_ctrl* curr_buff = (buff + (i*sizeof(struct buff_ctrl)));
struct tuple *ptr = (struct tuple*)malloc(buffer_size * sizeof(struct tuple));
curr_buff->buffer_ptr = ptr;//points to another array
curr_buff->in = 8;
curr_buff->out = 4;
curr_buff->numItems = 7;
curr_buff->done = 0;
printf("%p\n",curr_buff);
}
然后,我需要通过&#39; buff&#39;使用pthread_create创建线程时,指针作为参数:
pthread_create(&mapThd, NULL, mapper, (void*)buff);
pthread_join(mapThd, &status);
free(buff);
/*end of main*/
我的函数指针如下:
void* mapper(void *buff)
{
struct buff_ctrl* arr = (struct buff_ctrl *)buff;
struct buff_ctrl* temp_ptr;
printf("######################################################\n");
for(int k=0; k<user_num; k++)
{
/*Printing just to check values */
temp_ptr = arr + (k*sizeof(struct buff_ctrl));
printf("buffer ptr = %p\n", temp_ptr->buffer_ptr);
printf("in = %d\n", temp_ptr->in);
printf("out = %d\n", temp_ptr->out);
printf("numItems = %d\n", temp_ptr->numItems);
}
printf("######################################################\n");
pthread_exit((void*)buff);
}
但是,当我打印&#39; buffer_ptr&#39;的值时从创建的线程(只有一个),对于 ODD user_num的数量,总是有一个元素的数组&#39; buff&#39;在 pthread_create语句之后给出了垃圾值!删除对pthread的调用后,在main本身中检查值时,它运行正常。
答案 0 :(得分:4)
这一行
struct buff_ctrl* curr_buff = (buff + (i*sizeof(struct buff_ctrl)));
应该是
struct buff_ctrl* curr_buff = buff + i;
buff + i
是指针算术,编译器已经采用了它的大小
buff
指出的对象。通过执行i*sizeof(struct buff_ctrl)
您正在分配
指针可能在分配的内存之后。
作为一般建议:
不要施放malloc
。而不是使用sizeof(<type>)
,使用sizeof *variable
,这更安全,因为
在撰写sizeof(<type>)
时,更容易犯错误。
所以:
struct buff_ctrl *buff = malloc(user_num * sizeof *buff);
...
struct tuple *ptr = malloc(buffer_size * sizeof *ptr);
你不需要声明一个单独的指针,你可以这样做:
for(int i=0; i<user_num; i++)
{
buff[i].buffer_ptr = malloc(buffer_size * sizeof *buff[i].buffer_ptr);
buff[i].in = 8;
buff[i].out = 4;
buff[i].numItems = 7;
buff[i].done = 0;
}
此外,您应该始终检查malloc
的返回值。如果它返回
NULL
,您无法访问该内存。
答案 1 :(得分:3)
这是错误的:
struct buff_ctrl* curr_buff = (buff + (i*sizeof(struct buff_ctrl)));
当您执行指针运算时,它以指针指向的大小为单位运行,因此您不需要乘以sizeof
。结果,您实际上是两次乘法并在数组边界外访问。
只需将buff
视为数组,而不是处理指针。
for(int i=0; i<user_num; i++)
{
struct tuple *ptr = malloc(buffer_size * sizeof(struct tuple));
buff[i].buffer_ptr = ptr;//points to another array
buff[i].in = 8;
buff[i].out = 4;
buff[i].numItems = 7;
buff[i].done = 0;
}
答案 2 :(得分:1)
你有一个根本性的错误。
指针算术通过在指针类型的倍数中添加偏移量来工作,因此自己添加偏移量将无法正常显示。
如果它是char *
指针,那么您需要手动添加偏移量,增量将乘以1。但在你的情况下,n
的增量乘以指针基类型的大小。
有时候使用附加符号做指针算术是有道理的,但大多数时候它更容易编写索引符号。