[英]pointer without a malloc
#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
我从这篇文章中学到 ,我需要使用malloc分配内存,因此我将其更改为如下所示,并且可以正常工作:
- struct stat *something;
+ struct stat *something = malloc(sizeof(struct stat));
在先前但相关的练习中,我没有使用malloc,并且它起作用了。 我搞不清楚了! 为什么在下面的行“ * struct dirent b; ”中不需要malloc?
或者,换句话说,我们如何才能知道有效负载太多并使用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的新手,也很无知-请保持温柔! :)
问题所在
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)
readdir
返回指向有效位置的指针,该函数本身负责使用有效对象并返回指向该对象的指针。 但是,您不能执行free(b)
:
返回值
成功后,
readdir()
返回一个指向dirent结构的指针。 (此结构可能是静态分配的;请勿尝试将其free(3)
。)
readdir
返回一个指向struct dirent
的指针。 这样做: b = readdir(a)
用readdir
返回的新值覆盖值b
。
所以b
先前已使用malloc
调用中分配的内存进行了初始化,该值已被覆盖,您现在可能会发生内存泄漏。
您可能想知道然后是否需要在readdir
调用之后在b
free
调用。 要回答这个问题,您必须查阅文档。 在这种情况下,答案是否定的 。
从readdir
的文档中:
成功后,readdir()返回一个指向dirent结构的指针。 (此结构可能是静态分配的;请勿尝试将其释放(3)。)
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 *路径名,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
在struct dirent *b
的有效指针。 这就是为什么它起作用。
通常,任何指针,无论是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)。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.