如何释放主线程函数分配的内存

时间:2019-07-10 06:42:08

标签: c memory-management pthreads free

我已经在线程函数 <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="300dp" xmlns:app="http://schemas.android.com/apk/res-auto" app:cardElevation="3dp" android:layout_margin="8dp"> <!-- <FrameLayout android:layout_margin="10dp" android:layout_width="match_parent" android:layout_height="wrap_content">--> <VideoView android:layout_width="match_parent" android:id="@+id/video_view" android:layout_height="400dp" /> <!-- </FrameLayout>--> <!--remeember to add progress bar when loading--> </androidx.cardview.widget.CardView> 中分配了heap内存,该存储空间用于计算堆区域中的值,以便主函数可以看到它。

这是线程函数定义:

f1

在上面的代码中,void *f1(void *input){ int sum = (int*)malloc(sizeof(int)); /* Do calculation */ pthread_exit((void*)&sum); } 是堆分配的存储,其地址作为返回值传递到sum中的sum1

main() join中的线程是这样的:

main()

一旦检索到值,我就想void *sum1; pthread_join(tid1,(void**)&sum1); 分配的内存。 当我在主体上使用free时,它会像free

那样抱怨

我如何显着和安全地munmap_chunk(): invalid pointer此记忆?

2 个答案:

答案 0 :(得分:5)

您的代码中的问题是使用了广播。在大多数情况下,C语言中的指针强制转换表示错误的构造。值得注意的是,在此示例中,如果正确使用了构造,则不需要强制转换:

// no cast required because malloc returns void * and void * can be converted
// to a pointer to int without a cast
int *sum = malloc(sizeof (int));

// no cast required because int * can be converted to a void * without a cast
pthread_exit(sum);

void *sum1;

// no cast required because the address of void * is a void **!
pthread_join(tid1, &sum1);

唯一需要强制转换的地方是如果现在将此void * 转换为int *内联:

int value = *(int *)sum1;

,但是您也可以通过分配将其转换,然后再次不需要强制转换:

int *value_ptr = sum1;
printf("The value was %d\n", *value_ptr);
free(value_ptr);

经验法则是,如果您比编译器更了解某些内容,则可以进行强制类型转换,例如“将值截断为uint8_t”或“此空指针实际上指向int,但我不是将它分配给一个来保存击键”-但是通常只是为了使警告静音而不能。


一些程序员写这样的代码:

int *ptr;
pthread_join(tid1, (void **)&ptr);

由于int *void *是不兼容的类型,可能具有或没有相同的表示形式甚至大小,并且尤其不能互为别名,因此这些代码并不严格符合。

答案 1 :(得分:4)

您应该发回指针,而不是其地址

pthread_exit(sum);
...
pthread_join(tid1, &sum1);

要从线程函数(使用returnpthread_exit()发送回来的指针)。
pthread_join(),您想获取此指针,但是pthread_join()的结果是一个整数,以报告成功/失败。
然后,我们必须声明一个指针变量(此处为sum1来存储预期结果,并向pthread_join()提供此变量的地址,以便可以对其进行更新(与我们为{{ 1}},以便更新提取的变量。