我的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,他也找不到任何东西。有人可能有任何线索如何检索我的错误,有什么建议吗?
答案 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);
}
}