C - 没有 malloc 的指针


#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(){
struct stat *something;
stat("/etc/profile", something);
printf("%dn", something->st_gid);
free(something);
return 0;
}
$ ./a.out
Segmentation fault

我从这篇文章中了解到我需要使用 malloc 分配内存,所以我将其更改为如下所示,它有效:

-       struct stat *something;
+       struct stat *something = malloc(sizeof(struct stat));

在之前但相关的练习中,我没有使用malloc,它已经奏效了。 我迷路了! 为什么我不需要malloc来表示下面的">*struct direntb;">行?

或者,换个说法,我们怎么知道有效载荷太多并使用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 %sn", argv[1]);
return 1;
}
// - malloc question about this very next line
struct dirent *b; 
while (( b = readdir(a)) != NULL){
printf("%s %lun", b->d_name, b->d_ino);
}
int closing = closedir(a);
printf("in closing, status is %dn", 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呼叫后拨打freeb。要回答这个问题,您必须查阅您的文档。在这种情况下,答案是否定的

readdir文档中:

成功后,readdir() 返回一个指向 dirent 结构的指针。(这 结构可以静态分配;不要试图释放(3)它。

int main(){
struct stat *something;
stat("/etc/profile", something);
printf("%dn", something->st_gid);
free(something);
return 0;
}

上面的代码有多个问题,

  1. 您正在使用未指向有效位置的something,并且 再次使用它作为缓冲区来存储stat()返回的信息。

int stat(const char *pathname, struct stat *statbuf);

stat()返回有关文件的信息,在statbuf指向的缓冲区中,因此您的statbuf(某物)应该是一个有效的缓冲区,其大小足以存储文件的信息,即struct stat的大小。

  1. 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 %lun", b->d_name, b->d_ino);
}

让我们readdir()一下探索一下,

struct dirent *readdir(DIR *dirp);readdir() 函数返回一个 指向表示下一个目录条目的 dirent 结构的指针 DIRP 指向的目录流。 它在到达时返回 NULL。 目录流的结束或发生错误。

您会看到readdir()返回一个struct dirent类型的指针,该指针使bstruct dirent *b有效的指针。这就是它奏效的原因。

通常任何指针无论是int *ptr还是char *ptrstruct student *ptr,它都应该具有valid address和有效的地址可以动态分配地址某个变量的地址

情况 1struct stat *something;这里somethingstruct stat类型的指针,并且未初始化。

当您执行stat("/etc/profile", something);时,您正在尝试将/etc/profile信息存储到未初始化的something中。相反,您应该将/etc/profile的信息存储到something

struct stat info;
struct stat *something = &info;
stat("/etc/profile",something );

情况2struct dirent *b;bstruct dirent类型的指针,它也应该有有效的地址。b = readdir(a);readdir返回值分配给b,所以现在你可以执行b->d_name等。

readdir()的手册页

成功后,readdir() 返回一个指向 dirent 结构的指针。 (这 结构可以静态分配;不要试图释放(3)它。

相关内容

  • 没有找到相关文章

最新更新