C 有史以来最奇怪的分割错误
好的,基本上我正在写一个程序,它接受两个目录,并根据提供的选项对它们进行处理。问题是,当我看不到问题时,它会给我分段错误。导致故障的代码如下所示:C 有史以来最奇怪的分割错误,c,bash,segmentation-fault,C,Bash,Segmentation Fault,好的,基本上我正在写一个程序,它接受两个目录,并根据提供的选项对它们进行处理。问题是,当我看不到问题时,它会给我分段错误。导致故障的代码如下所示: #!/bin/bash clear echo Running testing script echo Removing old TestDirectory rm -r ./TD echo Creating new copy of TestDirectory cp -r ./TestDirectory ./TD echo Building progra
#!/bin/bash
clear
echo Running testing script
echo Removing old TestDirectory
rm -r ./TD
echo Creating new copy of TestDirectory
cp -r ./TestDirectory ./TD
echo Building program
make clean
make
echo Running mysync
./mysync ./TD/Dir1 ./TD/Dir2
echo Finished running testing script
编辑:更新代码以包含我的整个源文件
#include <unistd.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#define OPTLIST "am:npruv"
#define DEFAULT_MOD_TIMES 1
typedef struct
{
/* Boolean toggle to indicate whether hidden files should be
processed or not */
bool processHiddens;
/* Integer number of seconds such that files with modification
times that differ by less than this value are considered the
same */
int timeResolution;
/* Boolean toggle to indicate whether the actual synchronisation
(file creation and overwriting) should be performed or not */
bool performSync;
/* Boolean toggle to indicate whether subdirectories should be
recursively processed or not */
bool recursive;
/* Boolean toggle to indicate whether to print the combined
directory structure or not */
bool print;
/* Boolean toggle to indicate whether modification times and
permissions should be updated or not */
bool updateStatus;
/* Boolean toggle to indicate whether verbose output should be
printed or not */
bool verbose;
/* The name of the executable */
char *programname;
} OPTIONS;
int main(int argc, char *argv[])
{
static OPTIONS options;
//static TOPLEVELS tls;
int opt;
char **paths;
/*
* Initialise default without options input.
* Done the long way to be more verbose.
*/
opterr = 0;
options.processHiddens = false;
options.timeResolution = DEFAULT_MOD_TIMES;
options.performSync = true;
options.recursive = false;
options.print = false;
options.updateStatus = true;
options.verbose = false;
options.programname = malloc(BUFSIZ);
options.programname = argv[0];
/*
* Processing options.
*/
while ((opt = getopt(argc, argv, OPTLIST)) != -1)
{
switch (opt)
{
case 'a':
options.processHiddens = !(options.processHiddens);
break;
case 'm':
options.timeResolution = atoi(optarg);
break;
case 'n':
options.performSync = !(options.performSync);
break;
case 'p':
options.print = !(options.print);
break;
case 'r':
options.recursive = !(options.recursive);
break;
case 'u':
options.updateStatus = !(options.updateStatus);
break;
case 'v':
options.verbose = !(options.verbose);
break;
default:
argc = -1;
}
}
/*
* Processing the paths array for top level directory.
*/
char **tempPaths = paths;
while (optind < argc)
{
*tempPaths++ = argv[optind++];
}
if (argc -optind + 1 < 3)
{
fprintf(stderr, "Usage: %s [-amnpruv] dir1 dir2 [dirn ... ]\n", options.programname);
exit(EXIT_FAILURE);
}
else
{
//processTopLevelDirectories(tls, paths, nDirs, options);
exit(EXIT_SUCCESS);
}
return 0;
}
但是,如果我尝试使用完全相同的命令手动运行程序:
./mysync ./TD/Dir1 ./TD/Dir2
我在test1和test2之间发现了一个分段错误。但是,如果我只是将/
附加到任何一个目录,或者同时附加到两个目录,那么它会再次工作。有什么想法吗,伙计们
编辑:source_collection.h基本上是所有支持的源代码,到目前为止它们还没有实现,所以它们不会引起任何问题。选项是一个提供的结构,因此它应该是无错误的。当前源代码仍在进行中,因此仍有一些代码丢失,以及一些代码被注释掉。基本上,在一天结束时,该程序的目标是接收n个带有选项的目录并同步这些目录。您需要使用
strcpy()
将argv[optind]
复制到您刚刚分配的*tempPath
空间中
事实上,您正在破坏(泄漏)分配的内存,然后谁知道还会出什么问题
还有,为什么你需要复制你的论点?如果不修改它们,则不需要复制它们
这就完全消除了循环和临时变量
在评论中回答问题 [W] 你说我分配的内存泄漏是什么意思 您的原始代码是:
*tempPaths = malloc(BUFSIZ);
*tempPaths = argv[optind];
第一条语句将内存分配给*临时路径;然后,第二个指针用指针argv[optind]覆盖(唯一引用)该指针,从而确保您无法释放分配的内存,同时确保您没有使用它。此外,如果您随后尝试释放。。。嗯,到这个阶段,它将是路径
,而不是临时路径
。。。然后,您试图释放从未分配的内存,这也是一件坏事™.
我也不太明白你所说的“复制你的论点”是什么意思。您指的是用于命令行的两个目录还是其他目录
您的代码正在复制传递给程序的参数(目录名);使用strdup()
(或大致为strdup()
)的修订解决方案在argv[optind]
中复制数据。但是,如果要对数据执行的所有操作都是在不更改数据的情况下读取数据,则可以简单地复制指针,而不是复制数据。(即使要修改参数,如果小心,也可以使用原始数据,但复制更安全。)
最后不会char**path=&argv[optind];只要给我一个目录就行了
没有;它将为您提供一个指向字符串指针的以null结尾的列表的指针,您可以单步执行:
for (i = 0; paths[i] != 0; i++)
printf("name[%d] = %s\n", i, paths[i]);
裸最小工作代码 正如在一篇评论中指出的,扩展崩溃代码的基本问题(除了我们没有标题这一事实)是
path
变量没有初始化为指向任何东西。难怪代码会崩溃
根据修改后的示例-去掉选项处理:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char **paths;
optind = 1;
paths = &argv[optind];
if (argc - optind + 1 < 3)
{
fprintf(stderr, "Usage: %s dir1 dir2 [dirn ... ]\n", argv[0]);
exit(EXIT_FAILURE);
}
else
{
char **tmp = paths;
while (*tmp != 0)
printf("<<%s>>\n", *tmp++);
}
return 0;
}
#包括
#包括
#包括
int main(int argc,char*argv[])
{
字符**路径;
optind=1;
路径=&argv[optind];
如果(argc-optind+1<3)
{
fprintf(标准,“用法:%s dir1 dir2[dirn…]\n”,argv[0]);
退出(退出失败);
}
其他的
{
char**tmp=路径;
而(*tmp!=0)
printf(“\n”,*tmp++”);
}
返回0;
}
此版本执行内存分配:
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
optind = 1;
if (argc - optind + 1 < 3)
{
fprintf(stderr, "Usage: %s dir1 dir2 [dirn ... ]\n", argv[0]);
exit(EXIT_FAILURE);
}
else
{
int npaths = argc - optind;
char **paths = malloc(npaths * sizeof(*paths));
// Check allocation!
char **tmp = paths;
int i;
printf("n = %d\n", npaths);
for (i = optind; i < argc; i++)
{
*tmp = malloc(strlen(argv[i])+1);
// Check allocation!
strcpy(*tmp, argv[i]);
tmp++;
}
for (i = 0; i < npaths; i++)
printf("<<%s>>\n", paths[i]);
}
return 0;
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
optind=1;
如果(argc-optind+1<3)
{
fprintf(标准,“用法:%s dir1 dir2[dirn…]\n”,argv[0]);
退出(退出失败);
}
其他的
{
int npath=argc-optind;
字符**路径=malloc(npath*sizeof(*路径));
//检查分配!
char**tmp=路径;
int i;
printf(“n=%d\n”,n路径);
对于(i=optind;i
您已确定SEGFULT发生在以下线路之一上:
*tempPaths = malloc(BUFSIZ);
*tempPaths = argv[optind];
argv
中的argc
条目不太可能少于argc,因此我们推断问题在于分配给*tempPath
,因此tempPath
不能是有效的指针
由于您没有显示路径是如何初始化的,因此无法深入挖掘。很可能path
中的argc
成员少于paths
,因此您的tempPaths++
会导致您跳过最后一个条目。对不起,但您说我分配的内存泄漏是什么意思?我也不太明白你所说的“复制你的论点”是什么意思。您指的是用于命令行的两个目录还是其他目录?最后不会char**path=&argv[optind]代码>只需给我一个目录,就可以了?即使在将代码更改为*tempPath++=argv[optind++]之后也是如此代码>我原来的问题仍然存在。@jon2512chua:代码中有足够多的问题,您表明剩余的问题可能存在于任何地方。如果您可以提供一个最小崩溃程序(一个编译但说明崩溃的最小程序),那么
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char **paths;
optind = 1;
paths = &argv[optind];
if (argc - optind + 1 < 3)
{
fprintf(stderr, "Usage: %s dir1 dir2 [dirn ... ]\n", argv[0]);
exit(EXIT_FAILURE);
}
else
{
char **tmp = paths;
while (*tmp != 0)
printf("<<%s>>\n", *tmp++);
}
return 0;
}
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
optind = 1;
if (argc - optind + 1 < 3)
{
fprintf(stderr, "Usage: %s dir1 dir2 [dirn ... ]\n", argv[0]);
exit(EXIT_FAILURE);
}
else
{
int npaths = argc - optind;
char **paths = malloc(npaths * sizeof(*paths));
// Check allocation!
char **tmp = paths;
int i;
printf("n = %d\n", npaths);
for (i = optind; i < argc; i++)
{
*tmp = malloc(strlen(argv[i])+1);
// Check allocation!
strcpy(*tmp, argv[i]);
tmp++;
}
for (i = 0; i < npaths; i++)
printf("<<%s>>\n", paths[i]);
}
return 0;
}
*tempPaths = malloc(BUFSIZ);
*tempPaths = argv[optind];