#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(){
struct stat *something;
stat("/etc/profile", something);
printf("%d\n", something->st_gid);
free(something);
return 0;
}
$ ./a.out
Segmentation fault
我学会了from this post我需要使用malloc分配内存,所以我将其更改为如下,并且它可以工作:
- struct stat *something;
+ struct stat *something = malloc(sizeof(struct stat));
在先前但相关的练习中,我没有使用malloc,而且它有效。 我搞不清楚了! 为什么我不需要malloc用于下面的“ * struct dirent b; ”这一行?
或者,重新说一下,我们怎么知道有效载荷太多并且使用malloc?
#include <stdio.h>
#include <dirent.h>
int main(int argc, char *argv[]){
if (argc != 2){
printf("Error. Syntax: ls <somefolder> \n");
return 1;
}
DIR *a = opendir(argv[1]) ;
if (a == NULL){
printf("error. cannot open %s\n", argv[1]);
return 1;
}
// - malloc question about this very next line
struct dirent *b;
while (( b = readdir(a)) != NULL){
printf("%s %lu\n", b->d_name, b->d_ino);
}
int closing = closedir(a);
printf("in closing, status is %d\n", closing);
return 0;
}
C的新人,也无能为力 - 请温柔! :)
答案 0 :(得分:2)
的问题
struct stat *something;
stat("/etc/profile", something);
是something
是指向无处的未初始化指针,这会产生
未定义的行为,因为stat
会在无效地址上写一些内容。
使用malloc
为您分配内存并传递指向已分配的内存
内存位置为stat
以及它的工作原理。
但您不需要使用malloc
,只是不要将something
声明为struct stat something;
stat("/etc/profile", &something); // <-- look at the usage of &
指针:
stat
在&
中,您应该使用返回指针的something
- 运算符
struct dirent *b;
while (( b = readdir(a)) != NULL)
。
在你的其他程序中
free(b)
readdir
返回一个指向有效位置的指针,该函数本身就是
小心使用有效对象并返回指向它的指针。但是,你做不到
做readdir()
:
返回值
成功时,
free(3)
返回指向dirent结构的指针。 (此结构可能是静态分配的;请勿尝试CREATE table arp_table ( time VARCHAR(30), source_mac VARCHAR(30), destination_mac VARCHAR(30), source_ip VARCHAR(30), destination_ip VARCHAR(30), length VARCHAR(30) )
它。)
答案 1 :(得分:2)
struct dirent
返回指向b = readdir(a)
的指针。这样做:
b
会使用readdir
返回的新值覆盖值b
。
因此malloc
先前已使用free
调用的已分配内存进行初始化,因此该值已被覆盖,您现在可能会发生内存泄漏。
您可能想知道在b
电话结束后是否需要在readdir
上致电readdir
。要回答这个问题,你必须查阅你的文档。在这种情况下,答案是否。
来自ctest -V -R TestMembraneCellCrypt -N
的文档:
成功时,readdir()返回指向dirent结构的指针。 (这个 结构可以静态分配;不要试图释放(3)它。)
答案 2 :(得分:2)
int main(){
struct stat *something;
stat("/etc/profile", something);
printf("%d\n", something->st_gid);
free(something);
return 0;
}
以上代码有多个问题,
something
未指向有效位置,并且
再次使用它作为缓冲区来存储stat()
返回的信息。int stat(const char * pathname,struct stat * statbuf);
stat()
在statbuf
指向的缓冲区中返回有关文件的信息,因此您的statbuf
(某物)应该是有效的缓冲区,其大小足以存储文件的信息,即struct stat
的大小。
free(something);
来自free()手册页
如果传递给free()的参数与之前由POSIX.1-2008中的函数返回的指针不匹配,该函数像malloc()那样分配内存,或者如果通过调用free释放空间( )或realloc(),行为未定义。
现在来看其他代码:
// - malloc question about this very next line
struct dirent *b;
while (( b = readdir(a)) != NULL){
printf("%s %lu\n", b->d_name, b->d_ino);
}
让我们稍微探讨readdir()
,
struct dirent * readdir(DIR * dirp); readdir()函数返回一个 指向表示下一个目录条目的dirent结构的指针 dirp指向的目录流。它到达时返回NULL 目录流的结尾或发生错误。
您看到readdir()
会返回struct dirent
类型的指针,该指针会使b
进入。{1}}
struct dirent *b
一个有效的指针。这就是它起作用的原因。
答案 3 :(得分:0)
通常任何一个指针,无论是int *ptr
还是char *ptr
还是struct student *ptr
,它应该有valid address
和有效地址都可以动态分配地址或某个变量的地址。
案例1 :struct stat *something;
此处something
是struct stat
类型的指针且未初始化。
当您执行stat("/etc/profile", something);
时,您尝试将/etc/profile
信息存储到未初始化的something
中。您应该将/etc/profile
的信息存储到something
或
struct stat info;
struct stat *something = &info;
stat("/etc/profile",something );
案例2 :struct dirent *b;
b
是struct dirent
类型的指针,它还应具有有效地址。
b = readdir(a);
readdir
返回值已分配给b
,因此现在您可以执行b->d_name
等。
来自readdir()
成功时,readdir()返回指向dirent结构的指针。 (这个 结构可以静态分配;不要试图释放(3)它。)