2010-09-07 75 views
5

我试图找出使用C代码的文件类型,这里是代码免费字符指针

char *get_file_type(char *path, char *filename) 
{ 
    FILE *fp; 
    char command[100]; 
    char file_details[100]; 
    char *filetype; 

    sprintf(command, "file -i %s%s", path, filename); 
    fp = popen(command, "r"); 
    if (fp == NULL) { 
     printf("Failed to run command\n"); 
     exit(1); 
    } 
    while (fgets(file_details, sizeof(file_details)-1, fp) != NULL) { 
     filetype = (strtok(strstr(file_details, " "), ";")); 
    } 

    pclose(fp); 
    return filetype; 
} 

在这里,而不是宣布命令[],我可以使用*命令?我试图使用它,但它抛出了一个异常。我们不需要释放像命令[]一样声明的变量?如果是的话如何?

回答

5

您可以使用char *command;,但是,你必须分配一些内存command与呼叫是指以malloc(),当你第i个内存完成的,它必须与以free()呼叫再次释放。如你所见,与使用固定大小的数组相比,这要做得更多(如你现在所做的那样),但它也可以变得更安全,因为你可以创建一个完全正确的缓冲区大小,而不是希望命令的总长度不会超过100个字符。

除此之外,你的代码有一个问题:filetype指针,该函数返回指向数组file_details内的位置,但阵列将由编译器执行return报表时予以清理,所以指针被函数返回是指一些被标记为“可以用于其他目的”的内存。

如果get_file_type的结果一次只对一个文件有效,那么可以将file_details数组声明为static,以便在调用该函数时保留该数组。

+0

我可以使用strdup吗? – 2010-09-07 09:22:03

+0

你可以,但是你必须记得在调用函数中调用'free'来避免内存泄漏。 – 2010-09-07 09:52:42

1

你为什么要改变它?对于临时缓冲区,人们通常用[]声明数组,以便他们不必担心垃圾处理。

+0

但你能解释我该怎么做吗? – 2010-09-07 08:33:22

+0

首先,根据'path'和'filename'的长度动态分配一个缓冲区,而不是默默地允许缓冲区溢出可能是有意义的。 (但是C99可变长度数组可以解决这个问题,使用'snprintf'而不是'sprintf'也是可取的。) – jamesdlin 2010-09-07 09:54:28

+4

这应该是一条评论... – zeboidlund 2012-12-01 07:05:14

11

当声明的数组:

char command[100]; 

编译器分配为它的存储器(在本例中100个字符)和command指向存储器的开始。您可以访问你分配的内存:

command[0] = 'a'; // OK 
command[99] = 'A'; // OK 
command[100] = 'Z'; // Error: out of bounds 

,但你不能改变的command值:

command = NULL;  // Compile-time error 

内存将在command超出范围可自动释放。


在声明指针:

char *commandptr; 

你只能创建一个变量指向char S,但它不指向任何东西。尝试使用没有初始化它是一个错误:

commandptr[0] = 'A'; // Undefined behaviour; probably a segfault 

你需要使用malloc自己分配内存:

commandptr = malloc(100); 
if (commandptr) { 
    // Always check that the return value of malloc() is not NULL 
    commandptr[0] = 'A'; // Now you can use the allocated memory 
} 

,并释放它当你完成它:

free(commandptr); 
+0

实际上,堆栈数组不会被释放,因为它不需要。 说实话,malloc和free是系统调用(好吧,它们的包装),而堆栈数组不是。 – KAction 2012-07-07 03:19:43