编辑2:这个问题似乎根植于被复制的文件总大小。我拿了我正在复制的源目录并从中删除了一些文件以减少存储空间,现在程序只能打印10份副本,再次总计大约150 mb,其中第11位将它带到165。减少或者在合理范围内(2-25个字符)增加文件名本身中的字符数似乎没有任何影响,所以我猜这个问题与目录路径缓冲区没有关系(无论如何,Xcode在这种情况下可能会得到相同的错误。)
这是否与bash脚本可以使用的堆栈内存上的硬帽有关?因为如果Xcode程序没有相同的限制,那么为什么它可以完美地运行超过6 gb的数据,但只能通过命令行(完全)运行大约150-160 mb。
如果它与命令行的限制或bash脚本可以使用多少内存有关,那么我的问题是如何才能正确地优化它以避免这种错误?
我正在编写一个程序,该程序接收给定目录的用户输入,并从参数创建一个副本及其内容在另一个目录中特定次数。当我使用clang从Xcode运行它时,它编译并运行完美,所有副本都没有问题,就我所见。当我尝试使用clang从命令行运行完全相同的程序时,它会产生大约4-5个副本,然后给出"分段错误11 :(核心转储)"。
编辑:它在Xcode上运行得很好,任意数量的副本(我已经尝试了总计大约6gb的150),当我从命令行运行它时可以运行4个副本(总共约160 mb),在第五天,它开始变得混乱。当我使用lldb(backtrack)进行调试时,我得到了以下内容:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x68)
* frame #0: 0x00007fffc32ce6a0 libsystem_c.dylib`flockfile + 4
frame #1: 0x00007fffc32d183c libsystem_c.dylib`fwrite + 72
frame #2: 0x0000000100001550 copy`fcopy(s_dir="/temp/", s_name="mov1 copy 7.mov", d_dir="/Users/Ziad/Downloads/temp 5/", d_name="mov1 copy 7.mov") at main.c:69
frame #3: 0x0000000100001818 copy`copy_contents(source_dir="/temp", dest_dir="/Users/Ziad/Downloads/temp 5") at main.c:100
frame #4: 0x0000000100001abc copy`dir_copy(search_d="/", copy_d="temp", dest_d="/Users/Ziad/Downloads/", count=25) at main.c:133
frame #5: 0x0000000100001bbf copy`distribute(search_d="/", copy_d="temp", username="Ziad", c_each=25) at main.c:153
frame #6: 0x0000000100001db7 copy`main(argc=1, argv=0x00007fff5fbffa80) at main.c:179
frame #7: 0x00007fffc325c235 libdyld.dylib`start + 1
请求的大部分代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
enum {
FOUND = 0,
NFOUND = 1,
RERROR = 3,
OERROR = 4,
DUPLIC = 5,
} ErrorCodes;
typedef struct dirent dirent;
typedef DIR dir;
typedef FILE file;
int dir_copy(char* search_d, char* copy_d, char* dest_d, size_t count);
int dir_check(char* search_d, char* find_d) {
dir* dirp = opendir(search_d);
dirent* dp;
while (dirp) {
if ((dp = readdir(dirp)) != NULL) {
if (strcmp(dp->d_name, find_d) == 0) {
closedir(dirp);
return FOUND;
}
}
else {
closedir(dirp);
return NFOUND;
}
}
return OERROR;
}
int dir_test(char* dir_t) {
dir* dirp = opendir(dir_t);
if (dirp) {
closedir(dirp);
return FOUND;
}
else {
return OERROR;
}
}
int fcopy(char* s_dir, char* s_name, char* d_dir, char* d_name) {
char buf[BUFSIZ], sbuf[BUFSIZ], dbuf[BUFSIZ];
size_t n;
sprintf(sbuf, "%s%s", s_dir, s_name);
sprintf(dbuf, "%s%s", d_dir, d_name);
file* file_s = fopen(sbuf, "r");
file* file_d = fopen(dbuf, "w");
while ((n = fread(buf, sizeof(char), sizeof(buf), file_s)) > 0) {
if (fwrite(buf, sizeof(char), n, file_d) != n) {
return -1;
}
}
return 0;
}
void copy_contents(char* source_dir, char* dest_dir) {
dir* dirp_s = opendir(source_dir);
dir* dirp_d = opendir(dest_dir);
dirent* dp_s;
dirent* dp_d;
char sbuf[BUFSIZ], dbuf[BUFSIZ], cbuf[BUFSIZ];
char sdbuf[BUFSIZ], ddbuf[BUFSIZ];
sprintf(sdbuf, "%s", source_dir);
sprintf(ddbuf, "%s", dest_dir);
while (dirp_s && dirp_d) {
errno = 0;
if ((dp_s = readdir(dirp_s)) != NULL) {
sprintf(sbuf, "%s/", sdbuf);
sprintf(dbuf, "%s/", ddbuf);
sprintf(cbuf, "%s%s", sbuf, dp_s->d_name);
if (dir_test(cbuf) == FOUND) {
if (strcmp(dp_s->d_name, ".") == 0 || strcmp(dp_s->d_name, "..") == 0) {
;
}
else {
dir_copy(sbuf, dp_s->d_name, dbuf, 1);
}
}
else {
fcopy(sbuf, dp_s->d_name, dbuf, dp_s->d_name);
}
}
else {
closedir(dirp_s);
closedir(dirp_d);
break;
}
}
}
int dir_copy(char* search_d, char* copy_d, char* dest_d, size_t count) {
int dcount;
char sbuf[BUFSIZ], cbuf[BUFSIZ], dbuf[BUFSIZ];
char sdbuf[BUFSIZ], cdbuf[BUFSIZ], ddbuf[BUFSIZ];
sprintf(sdbuf, "%s", search_d);
sprintf(cdbuf, "%s", copy_d);
sprintf(ddbuf, "%s", dest_d);
if (dir_check(sdbuf, cdbuf) == FOUND) {
for (dcount = 0; dcount < count; dcount++) {
sprintf(sbuf, "%s%s", sdbuf, cdbuf);
if (dcount > 0) {
sprintf(dbuf, "%s%s %d", ddbuf, cdbuf, dcount);
}
else {
sprintf(dbuf, "%s%s", ddbuf, cdbuf);
}
sprintf(cbuf, "%s %d", cdbuf, dcount);
if (dir_check(search_d, cbuf) == FOUND) {
return DUPLIC;
}
mkdir(dbuf, ACCESSPERMS);
copy_contents(sbuf, dbuf);
}
return FOUND;
}
return NFOUND;
}
char* read_in(char* str, int buflen, FILE* stream)
{
if (fgets(str, buflen, stream) != 0)
{
size_t len = strlen(str);
if (len > 0 && str[len - 1] == '\n')
str[len - 1] = '\0';
return str;
}
return 0;
}
int main(int argc, char* argv[]) {
dir_copy("/", "temp", "/Users/", 7);
return 0;
}
dir_copy()
获取要搜索的目录的第一个参数(search_d
),即要复制的目录的第二个参数(copy_d
),目标目录的参数({ {1}}),以字符串形式传入。最后一个参数是dest_d
,它是应在size_t count
中生成的copy_d
的副本数。