没有malloc的指针

时间:2018-03-14 02:52:45

标签: c 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

我学会了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的新人,也无能为力 - 请温柔! :)

4 个答案:

答案 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()

  

man 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;
}

以上代码有多个问题,

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

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

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

    1. free(something);
    2. 来自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;此处somethingstruct 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; bstruct dirent类型的指针,它还应具有有效地址。  b = readdir(a); readdir返回值已分配给b,因此现在您可以执行b->d_name等。

来自readdir()

的手册页
  

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