C程序:生成目录,链接被破坏

时间:2014-10-14 10:03:17

标签: c

我的C程序中有一个非常奇怪的问题,我不知道如何将我的代码剪切到所需的但我会尝试。 所以我生成了一堆这种结构的目录和子目录:

AA / - 和子目录:0 /,1 /,2 / ...... 同样适用于BB /

我这样做:

char *my_location = "/Users/example/Documents/";
int total = 2;
int i, j, total_subDir;
char ***file_location;
total_subDir = 100;
file_location = malloc(sizeof(char**)* total);
char *suffix = "AA/"; char *suffix2 = "BB/";

int my_loc_len = strlen(my_location);

for (i = 0; i < total; i++) {

    char *temp;
    file_location[i] = malloc(sizeof(char*)* total_subDir);
    temp = malloc(sizeof(char)* (my_loc_len + 4));
    memcpy(temp, my_location, my_loc_len);
    if (i == 0) memcpy(&temp[my_loc_len], suffix, 3);
    else memcpy(&temp[my_loc_len], suffix2, 3);

    temp[my_loc_len + 3] = '\0';
    int temp_length = strlen(temp);
    mkdir(temp, 0777);

    for (j = 0; j < total_subDir; j++) {
        char *subdir_name;

       subdir_name = malloc(sizeof(char)* 20);
        sprintf(subdir_name, "%d", j);
        int digit_num = strlen(subdir_name);

       file_location[i][j] = malloc(sizeof(char) *(temp_length + digit_num + 1 + 1));
        memcpy(file_location[i][j], temp, temp_length);
        memcpy(&file_location[i][j][temp_length], sub_dir_name, digit_num);
        memcpy(&file_location[i][j][temp_length + digit_num], "/", 1);

        file_location[i][j][temp_length + digit_num + 1] = '\0';

        mkdir(file_location[i][j], 0777);
        free(subdir_name);
    }
    free(temp);
}

我只在一个方法中使用这组链接,它只是提供保存某些文件的路径,所以像:

  void save_information(char **some_info, char *location) 

其中location是其中一个子目录,因此:file_location [i] [j];所以我永远不会改变链接。

然而,有时会发生指向目录的链接被破坏,所以我得到类似的东西:“/ Users / ex1mple / Documents /”,通常只在一个链接中。当我多次使用相同的数据重新运行我的程序时,有时会出现损坏的文件,有时它不是,并且它并不总是相同的链接......

我觉得我的问题没有一个答案,我想我在某处有一些内存写/问题,但我无法重建它的位置。我在代码上运行valgrind,他也找不到任何东西。有人可能有任何线索如何检索我的错误,有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您可以通过正确使用Macros,避免memcpy,不必要的malloc,使用通用functions并为上述任务引入error-checking来改进您的代码

以下代码执行您的预期任务。

#define SUBDIR          100
#define PERMISSION      0777
#define PARENT_PATH     "/Users/example/Documents/"

/* Function to create Directories */
void create_dir (char *file_name, int PERM)
{
    printf("Creating Directory : [%s]\n", file_name);
    if (-1 == mkdir(file_name, PERM)) {
        fprintf(stderr, "Error in mkdir: [%d][%s]\n", errno, strerror(errno));
        exit(EXIT_FAILURE);
    }
    return;
}

int main (int argc, char **argv)
{
    if (argc != 2)
    {
        if (1 == argc) {
            fprintf(stderr, "Usage : %s <NO_OF_SUBDIR>\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    if (atoi(argv[1]) > 26) {
         fprintf(stderr, "Value should be lesser than 26 (A-Z)\n");
         exit(EXIT_FAILURE);
    }

    int i, j, suffix = 65;               /* ASCII value for A is 65 */

    /* Filename not to exceed 1024 characters */
    char *temp = malloc (sizeof(char) * 1024);      

    for (i=0; i<atoi(argv[1]); i++)
    {       
        sprintf(temp, "%s/%c/", PARENT_PATH, suffix);           

        /* Creates Directory, ex: For input 1, creates dir A*/
        create_dir(temp, PERMISSION);   
        for (j=0; j<SUBDIR; j++)
        {
            /* Creates Sub-directory ex: /A/0 .. /A/99/ */
            sprintf(temp, "%s/%c/%d", PARENT_PATH, suffix, j);
            create_dir(temp, PERMISSION);
        }
        /* Increments to ASCII of next Alphabet */ 
        suffix++;
    }       
    free(temp);
    return 0;          
}

编译&amp;执行:

$ gcc -o exe 2.c -Wall -Wextra
$ ./exe 1          /* Creates dir A, with 0-99 sub directories */
$ ./exe 2          /* Creates dir A and B, with 0-99 sub directories in each */
$ ./exe 26         /* Creates dir A to Z,  with 0-99 sub directories in each */
$ ./exe 27
Value should be lesser than 27 (A-Z)

答案 1 :(得分:0)

我认为Saurabh Meshram的解决方案是首选。我仍然想展示这个版本,只是为了向提问者说明,他的代码如何通过删除不必要的mallocs并使用字符串操作而不是memcpy来实现。我认为可读性已大大提高。

#define LOCATION_MAXLEN 50
#define SUFFIX_MAXLEN   5
#define NUMBER_MAXLEN   5
#define TOTAL           2
#define TOTAL_SUBDIR    100
#define PERMISSION      0777

...

char *my_location = "/Users/example/Documents/";
int i, j;
char file_location[TOTAL][TOTAL_SUBDIR][LOCATION_MAXLEN];

char* suffix1 = "AA/",
    * suffix2 = "BB/";

for (i = 0; i < TOTAL; i++) {

    char temp[LOCATION_MAXLEN+SUFFIX_MAXLEN];
    strcpy_s(temp, my_location);
    strcat_s(temp, i == 0 ? suffix1 : suffix2);

    mkdir(temp, PERMISSION);

    for (j = 0; j < TOTAL_SUBDIR; j++) {
        char subdir_name[NUMBER_MAXLEN];
        sprintf_s(subdir_name, "%d", j);
        int digit_num = strlen(subdir_name);

        strcpy_s(file_location[i][j], temp);
        strcat_s(file_location[i][j], subdir_name);
        strcat_s(file_location[i][j], "/");

        mkdir(file_location[i][j], PERMISSION);
    }
}