如何将此临时 char* 变量复制到我的结构中以进行更永久的存储?
Posted
技术标签:
【中文标题】如何将此临时 char* 变量复制到我的结构中以进行更永久的存储?【英文标题】:How do I copy this temporary char* variable into my struct for more permanent storage? 【发布时间】:2021-11-06 22:27:24 【问题描述】:我正在尝试实现一个线程池,但在让我应该使用的文件路径比它们存在于 OnOpen 中的临时实例更永久地存储时遇到了很多麻烦来自ftw的功能。我不允许对每个处理的文件路径执行 malloc。
这是我目前必须尝试让 OnOpen 不向我的线程提供临时数据的方法,我对它在 memcpy 上崩溃的原因感到困惑。
我很想知道如何在不创建用于执行 memcpy 的多余 char* 数组的情况下从正在编辑的临时变量中获取数据的安全性。
typedef struct Task
void (*taskFunc)(char*);
char* arg;
Task;
void HashFunc(char* arg)
pthread_mutex_lock(&lock);
printf("%s\n", arg);
thingsDone++;
pthread_mutex_unlock(&lock);
static int OnOpen(const char* path, const struct stat* sb, int flags)//will send folder paths too
if(strstr(path, ".exe") || strstr(path, ".cfg")) return 0;
Task t =
.taskFunc = &HashFunc,
.arg = path
;
memcpy(t.arg, path, strlen(path));
while(taskCount == MAX_OPEN_FILE_HANDLES-1); //busy wait
submitTask(t);
return 0;
编辑:很好的反馈,但这不是我所需要的。
下面我将添加一些与我遇到问题的代码相关的内容,即线程池以及我如何使用任务结构,这可能有助于更好地了解可以做什么以及我该怎么做:
void executeTask(Task* task) task->taskFunc(task->arg);
void* threadFunc(void* arg)
Task task;
while (!(doneSending==1 && thingsDone == thingsToDo))
pthread_mutex_lock(&lock);
while (taskCount==0 && doneSending==0) pthread_cond_wait(&condQueue, &lock);
task = taskQueue[0];
for (int i = 0; i < taskCount-1; i++) taskQueue[i] = taskQueue[i+1];
taskCount > 0 ? --taskCount : 0;
pthread_mutex_unlock(&lock);
if (doneSending==0 || thingsDone<thingsToDo) executeTask(&task);
printf("%d, %d, %d, %d\n", taskCount, thingsDone, thingsToDo, doneSending);
void submitTask(Task task)
pthread_mutex_lock(&lock);
taskQueue[taskCount++] = task;
++thingsToDo;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&condQueue);
我的线程池由 8 个线程组成,这也是我的 taskQueue 的大小。
我以前有.arg = strcpy(temp, path)
,但由于 temp 是临时的,我在 hashFunc 中打印了错误的数据。
每个线程都应该有自己的 Task 结构的副本可以使用,以免它们相互干扰。
最终编辑:我得到了它的工作,这是它需要的外观:
volatile int taskIdx = 0, pathIdx = 0;
Task taskArray[MAX_OPEN_FILE_HANDLES];
char* pathQueue[MAX_OPEN_FILE_HANDLES];
void* threadFunc(void* args)
Task task;
while (!(doneSending==1 && taskIdx == pathIdx))
if (doneSending && taskIdx==pathIdx) break;
pthread_mutex_lock(&lock);
pthread_cond_wait(&condArray, &lock);
if (doneSending && taskIdx==pathIdx)
pthread_mutex_unlock(&lock);
break;
task = taskArray[taskIdx];
taskIdx = (taskIdx+1)%MAX_OPEN_FILE_HANDLES;
pthread_mutex_unlock(&lock);
executeTask(&task);
void submitTask(Task t)
pthread_mutex_lock(&lock);
taskArray[pathIdx] = t;
pathIdx = (pathIdx+1)%MAX_OPEN_FILE_HANDLES;
pthread_cond_signal(&condArray);
pthread_mutex_unlock(&lock);
static int OnOpen(const char* path, const struct stat* sb, int flags)
if(flags != FTW_F || strstr(path, ".cfg") || strstr(path, ".exe") || strstr(path, ".vscode") || strstr(path, "anticheat") || strstr(path, "Makefile")) return 0;
if (thingsToDo-thingsDone == MAX_OPEN_FILE_HANDLES) HashFunc((char*)path, thingsToDo++);
else
Task t =
.taskFunc = &HashFunc,
.filePath = strcpy(pathQueue[pathIdx], path)
;
submitTask(t);
return 0;
int main()
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&condArray, NULL);
for (int i=0; i<MAX_OPEN_FILE_HANDLES; i++)
if(pthread_create(&pool[i], NULL, &threadFunc, NULL) != 0) perror("pth_create");
pathQueue[i] = calloc(MAX_PATH_LENGTH, sizeof(char));
【问题讨论】:
您需要先为arg
指针分配内存,然后才能将memcpy
分配给它。
@500-InternalServerError 嗯...是的和否。 memcpy
不可使用
struct stat* sb
定义在哪里?
t.arg 是一个指针。你认为它指向什么?
【参考方案1】:
首先。
memcpy(t.arg, path, sizeof(path));
这个操作严重错误。 sizeof(path)
返回指针变量的大小。它与字符串的长度无关。
使用strcpy
。
只需将字符数组放入struct Task
。每个线程都有自己的副本,而不会干扰其他线程:
typedef struct Task
void (*taskFunc)(char*);
char arg[PATH_MAX];
Task;
strcpy(Task.arg, path);
编辑
如果每个线程都应该有自己的arg
副本(不是整个Task
),只需使用strdup()
。它比strlen()/malloc()/strcpy()
序列方便得多。
Task t =
.taskFunc = &HashFunc,
.arg = strdup(path),
;
当线程完成它的工作时,记得用free(t.arg)
释放内存。
【讨论】:
嗯...这并不是完全错误,但是...考虑一下memcpy
即使在此修复之后也能正常工作?
@4386427 这取决于哪些数据应该在每个线程中持久化,Task
还是路径?【参考方案2】:
-
您没有分配任何内存来存储
path
sizeof(path)
是给你指针的长度而不是 path
的长度。要获取字符串的长度,请使用strlen
memcpy(t.arg, path, sizeof(path));
仅复制数字 sizeof(char *)
字节,而不是整个字符串。
size_t arglen = strlen(path);
Task t =
.taskFunc = &HashFunc,
.arg = malloc(arglen + 1),
;
/* add some error checking */
strcpy(t.arg, path);
【讨论】:
以上是关于如何将此临时 char* 变量复制到我的结构中以进行更永久的存储?的主要内容,如果未能解决你的问题,请参考以下文章