gpt4 book ai didi

c - 了解作用域后堆栈使用错误

转载 作者:行者123 更新时间:2023-11-30 14:36:30 25 4
gpt4 key购买 nike

我正在使用 C 和 pthreads 库开发多线程客户端,使用 boss/worker 架构设计,并且在理解/调试范围后堆栈使用错误时遇到问题,该错误导致我的客户端失败。 (我对 C 有点陌生)

我尝试了多种方法,包括全局定义变量、传递双指针引用等。

Boss logic within main:
for (i = 0; i < nrequests; i++)
{

struct Request_work_item *request_ctx = malloc(sizeof(*request_ctx));
request_ctx->server = server;
request_ctx->port = port;
request_ctx->nrequests = nrequests;

req_path = get_path(); //Gets a file path to work on

request_ctx->path = req_path;

steque_item work_item = &request_ctx; // steque_item is a void* so passing it a pointer to the Request_work_item

pthread_mutex_lock(&mutex);
while (steque_isempty(&work_queue) == 0) //Wait for the queue to be empty to add more work
{
pthread_cond_wait(&c_boss, &mutex);
}
steque_enqueue(&work_queue, work_item); //Queue the workItem in a workQueue (type steque_t, can hold any number of steque_items)
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&c_worker);
}

Worker logic inside a defined function:
struct Request_work_item **wi;

while (1)
{
pthread_mutex_lock(&mutex);
while (steque_isempty(&work_queue) == 1) //Wait for work to be added to the queue
{
pthread_cond_wait(&c_worker, &mutex);
}
wi = steque_pop(&work_queue); //Pull the steque_item into a Request_work_item type
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&c_boss);

char *path_to_file = (*wi)->path; //When executing, I get this error in this line: SUMMARY: AddressSanitizer: stack-use-after-scope
...
...
...
continues with additional worker logic

我希望工作人员从队列中提取 work_item,取消引用这些值,然后执行一些工作。但是,我不断收到 AddressSanitizer: stack-use-after-scope,并且网上有关此错误的信息不是很丰富,因此我们将不胜感激。

最佳答案

这里的危险信号是 &request_ctx 是局部变量的地址。它不是指向用malloc分配的存储的指针,而是保存该存储的变量的地址。一旦作用域终止,该变量就会消失,即使 malloc-ed block 仍然存在。

也许修复方法只是删除此行中的 & 运算符的地址?

steque_item work_item = &request_ctx; // steque_item is a void* so passing
// it a pointer to the Request_work_item

如果我们这样做,那么评论实际上就是事实。因为否则我们会将 work_item 设为指向 Request_work_item 的指针

由于 work_item 的类型为 void*,因此不幸的是,它可以以任何一种方式编译。

如果队列另一端的项目的使用者将其提取为 Request_work_item *,那么您不仅可以访问超出范围的对象,还可以即使当消费者使用该对象时该对象恰好仍在生产者的范围内,也会出现类型不匹配。消费者最终使用生产者堆栈的一部分,就好像它是 Request_work_item 结构一样。 编辑:我发现您在使项目出队并以 (*wi)->path 方式访问它时使用了指针到指针。考虑改变设计以避免这样做。否则,wi 指针也必须动态分配和释放。生产者必须做类似的事情:

struct Request_work_item **p_request_ctx = malloc(sizeof *p_request_ctx);
struct Request_work_item *request_ctx = malloc(sizeof *request_ctx);

if (p_request_ctx && request_ctx) {
*p_request_ctx = request_ctx;
request_ctx->field = init_value;
// ... etc
// then p_request_ctx is enqueued.

然后,消费者必须释放该结构,并且还释放指针。这个额外的指针在这里看起来只是纯粹的开销;它不提供任何必要或有用的间接级别。

关于c - 了解作用域后堆栈使用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58033699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com