C程序:生成目录,链接损坏
我的C程序中有一个非常奇怪的问题,我不知道如何将代码裁剪到所需的程度,但我会尝试。 因此,我生成了一组这种结构的目录和子目录: AA/--和子目录:0/,1/,2/。。。 BB也一样/ 我是这样做的:C程序:生成目录,链接损坏,c,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 = ma
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);
}
其中location是其中一个子目录,因此:file_location[i][j];所以我从不改变链接
然而,有时目录的链接会被破坏,所以我会得到类似于“/Users/ex1mple/Documents/”的东西,通常只在一个链接中。当我使用相同的数据多次重新运行我的程序时,有时会出现损坏的文件,有时则不是,并且不总是相同的链接
我想我的问题没有一个答案,我想我在某处有一些内存写入/问题,但我无法重建它的位置。我运行valgrind在我的代码,他也没有找到任何东西。有人可能知道我如何检索错误,有什么建议吗?您可以通过正确使用
宏来改进代码,避免memcpy
,不必要的malloc
,使用通用函数
,并为上述任务引入错误检查
下面的代码执行您预期的任务
#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;
}
我认为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);
}
}
#定义位置_maxlen50
#定义后缀_MAXLEN 5
#定义数字\u最大值5
#定义总计2
#定义总细分100
#定义权限0777
...
char*my_location=“/Users/example/Documents/”;
int i,j;
字符文件位置[TOTAL][TOTAL][SUBDIR][location\u MAXLEN];
char*suffix1=“AA/”,
*后缀x2=“BB/”;
对于(i=0;i
在字符串操作中使用memcpy有什么特别的原因吗?那代码太可怕了。所有那些memcpy
调用让我毛骨悚然。我想整理一下,使用字符串函数,然后盘点一下。对于这类东西来说,C是一种令人讨厌的语言。你不能用更合适的吗。您也不应该编写sizeof(char)
。根据定义,等于1。我同意@DavidHeffernan对该代码的观点。您的一些malloc
s是完全冗余的。如果数组是固定长度的,那么只需在堆栈上分配它。还有,这些常量字符串。试着在函数开始时把它们放在一个地方。事实上,为了“向我们保证”您不会试图更改它们(因为在代码中很难遵循它们),请将它们定义为宏。如果将单个字符写入字符串,则不要使用memcpy
。那么,除了sizeof(char)之外,我应该写些什么,如何为char数组分配内存?如果我将其更改为字符串操作,则不会更改任何内容,我避免使用它们,因为它们会对终端符号进行冗余搜索,如果我知道它在哪里,避免这个很好,这看起来真的很好,谢谢。当我必须将多个字符串连接到另一个字符串上时,sprintf是要使用的方法吗?sprintf
将打印到一个字符串,因此您可以使用它将字符串(本例中的路径)与/
分隔符连接起来。适当使用宏
和函数
将减少您的代码,使其更易于阅读/理解和简单。添加错误检查将使代码易于调试。
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;
}
$ 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)
#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);
}
}