Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 有史以来最奇怪的分割错误_C_Bash_Segmentation Fault - Fatal编程技术网

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];