【发布时间】:2021-03-24 00:15:39
【问题描述】:
更新: 完全删除 print 语句(第 52 行),其他所有内容与下面的代码相同,这给了我 0 个错误。打印时(使用 philo[i])和此打印语句(为调试添加)中存在错误,但如果我在没有打印的情况下运行整个程序,则错误不存在。任何想法我做错了什么???
感谢您迄今为止的帮助。我已经根据目前收到的 cmets 进行了一些更改。
***** 原始(已编辑)问题 *****
我无法弄清楚为什么我会收到此错误,“未初始化的值是由堆栈分配创建的”。我从一个运行良好的完整程序开始,但给了我大量未初始化的值错误。通过排除所有函数并添加额外的打印语句,我已将问题追溯到几行代码。这段代码是用线程解决餐饮哲学家的问题(作业),所以不想发太多。我的代码现在是:
#include <all needed header files>
#define NUM_PHIL 5
#define MIN_EAT_TIME 10
pthread_t philosopher[NUM_PHIL]; // array to hold IDs for philosopher threads
pthread_mutex_t chopstick[NUM_PHIL]; // array to hold IDs for chopstick mutexes (locks)
// function definitions here:
int philosopherFun(int *philo);
// All others have been bypassed at the time of my current problem
int main(int argc, char *argv[]) {
int phil[NUM_PHIL]; // Philosopher numbers ("names")
for(int i = 0; i < NUM_PHIL; i++) {
phil[i] = i + 1;
}
for(int i = 0; i < NUM_PHIL; i++) {
// Print statement causes valgrind error to exist (as does calling a function using phil)
printf("Value phil[%d] = %d\n", i, phil[i]);
}
// Initilize mutexes for chopsticks, report error as needed
for(int i = 0; i < NUM_PHIL; i++) {
if(pthread_mutex_init( stuff here) < 0) {
// error reporting
// print statement uses i
}
}
for(int i = 0; i < NUM_PHIL; i++) {
if(pthread_create(&philosopher[i], NULL, (void*) philosopherFun, (void*) &phil[i] ) != 0) {
// error reporting
// print statement uses phil[i]
}
}
/* Code omitted as this is Homework */
// Join threads created for philosophers (using pthread_join)
// error reporting
// print statement uses phil[i]
// Destroy chopstick mutexes when done. (using pthread_mutex_destroy)
// error reporting
// print statement uses i
printf("The philosophers have all finished eating and its time for bed. Goodnight...\n");
return 0;
}
int philosopherFun(int *philo) {
return 0;
}
程序输出:
值 phil[0] = 1
值 phil[1] = 2
值 phil[2] = 3
值 phil[3] = 4
值 phil[4] = 5
哲学家们都吃完了,该睡觉了。晚安...
我的 Valgrind 错误是:
==46556== 堆摘要:
==46556== 退出时使用:0 个块中的 0 个字节
==46556== 总堆使用量:0 次分配,0 次释放,0 字节分配
==46556==
==46556== 所有堆块都被释放——不可能有泄漏
==46556==
==46556== 错误摘要:来自 1 个上下文的 10 个错误(抑制:0 来自 0)
==46556==
==46556== 上下文 1 中的 10 个错误:
==46556== 条件跳转或移动取决于未初始化的值
==46556== 在 0x7FFF205A395F: ??? (在 /dev/ttys000 中)
==46556== 由 0x7FFF2046FFFA: ??? (在 /dev/ttys000 中)
==46556== 由 0x7FFF20478CF0: ??? (在 /dev/ttys000 中)
==46556== 由 0x7FFF2049D8B8: ??? (在 /dev/ttys000 中)
==46556== 由 0x7FFF20475EF5: ??? (在 /dev/ttys000 中)
==46556== 由 0x7FFF20474061: ??? (在 /dev/ttys000 中)
==46556== by 0x1000038CD: main (philo.c:52)
==46556== 未初始化的值是由堆栈分配创建的
==46556== 在 0x7FFF20475FDF: ??? (在 /dev/ttys000 中)
==46556==
==46556== 错误摘要:来自 1 个上下文的 10 个错误(抑制:0 来自 0)
第 52 行是我的打印语句: printf("值 phil[%d] = %d\n", i, phil[i]);
我认为这导致了 5 个错误(phil[0] - phil[4]),我在第 68 行的 pthread_create(包括这行代码)中调用了哲人Fun,再次导致 5 个错误(每个线程 1 个) .这个函数目前只在第一行返回,所以我的程序的其余部分都没有涉及(尽管我开始时有 50-250 个错误,具体取决于我的参数和我排除的函数)。
我觉得我的 int 数组 (int phil[]) 导致了问题,但它立即被初始化,所以我不确定这是怎么发生的。请帮忙!
谢谢, 克里斯汀
已编辑...从省略的代码中添加了一些 cmets - 线程被加入并且互斥体被破坏
我还尝试通过在我的 main 函数之外声明 int phil[NUM_PHIL] 来使其成为全局,但这并没有改变 Valgrind 返回的错误。定义 phil[5] = {1, 2, 3, 4, 5};作为一个全球性的也没有帮助。
【问题讨论】:
-
您可以使用
-g编译标志添加调试符号。这将有助于 valgrind 等程序提供更多有用的输出。 -
'int phil[NUM_PHIL];'当线程尝试访问它时,该数组是否仍然存在?
-
像
// Numbered 1 to i + 1这样的评论在右边这样的评论比没用更糟糕。您花了很多精力将这些 cmets 格式化为在那里排成一行,而那是一个分散眼睛看代码的位置。不仅如此,注释只是重复了代码显然做了什么。写一个不添加任何信息的分散注意力的评论是浪费精力。 -
这也很麻烦:
(void*) philosopherFun你为什么要把philsopherFun转换成void *?使用强制转换粘贴错误是您做错了什么的标志。 -
通过基本的编译修复,valgrind 错误不会出现在发布的代码中。请使用minimal reproducible example 更新您的问题。