为什么结构指针后来没有取消引用 return 与未定义为指针的结构相同的值?
Why doesn't a struct pointer later dereferenced not return the same value as a struct that wasn't defined as a pointer?
我遇到 this post 讨论如何从 stat
库打印文件权限,但我对结构的定义如何工作感到困惑。
当我定义结构时,我总是像 struct struct_type *name
那样定义它们。但在示例中,结构定义为 struct struct_type name
(不是指针)。据我所知,根据您定义结构的方式,应该有两种不同的方式来访问信息。
选项一表示法
struct stat fileStat; //definition of struct
stat("<filename>", &fileStat); //execute the stat function
fileStat.member_name; //access a member of a struct
选项二表示法
struct stat *fileStat; //definition of struct
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
但是当我将所提供示例中的选项一符号切换为选项二时,我得到了非常不同的结果。这两个选项有什么不同?它不是在有效地做同样的事情吗?
示例代码
选项一符号程序
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
struct stat fileStat;
stat("main", &fileStat);
printf("Information for %s\n", argv[1]);
printf("---------------------------\n");
printf("File Size: \t\t%lld bytes\n", fileStat.st_size);
printf("Number of Links: \t%d\n", fileStat.st_nlink);
printf("File inode: \t\t%llu\n", fileStat.st_ino);
printf("File Permissions: \t");
printf( (S_ISDIR(fileStat.st_mode)) ? "d" : "-");
printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
printf("\n\n");
printf("The file %s a symbolic link\n", (S_ISLNK(fileStat.st_mode)) ? "is" : "is not");
return 0;
}
选项一符号输出
Information for (null)
---------------------------
File Size: 49960 bytes
Number of Links: 1
File inode: 58527531
File Permissions: -rwxr-xr-x
The file is not a symbolic link
选项二符号程序
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
struct stat *fileStat;
stat("main", fileStat);
printf("Information for %s\n", argv[1]);
printf("---------------------------\n");
printf("File Size: \t\t%lld bytes\n", fileStat->st_size);
printf("Number of Links: \t%d\n", fileStat->st_nlink);
printf("File inode: \t\t%llu\n", fileStat->st_ino);
printf("File Permissions: \t");
printf( (S_ISDIR(fileStat->st_mode)) ? "d" : "-");
printf( (fileStat->st_mode & S_IRUSR) ? "r" : "-");
printf( (fileStat->st_mode & S_IWUSR) ? "w" : "-");
printf( (fileStat->st_mode & S_IXUSR) ? "x" : "-");
printf( (fileStat->st_mode & S_IRGRP) ? "r" : "-");
printf( (fileStat->st_mode & S_IWGRP) ? "w" : "-");
printf( (fileStat->st_mode & S_IXGRP) ? "x" : "-");
printf( (fileStat->st_mode & S_IROTH) ? "r" : "-");
printf( (fileStat->st_mode & S_IWOTH) ? "w" : "-");
printf( (fileStat->st_mode & S_IXOTH) ? "x" : "-");
printf("\n\n");
printf("The file %s a symbolic link\n", (S_ISLNK(fileStat->st_mode)) ? "is" : "is not");
return 0;
}
选项二符号输出
Information for (null)
---------------------------
File Size: 5193343115435036343 bytes
Number of Links: 12487
File inode: 930377443599221576
File Permissions: -r-x--x---
The file is not a symbolic link
这不是替代符号
struct stat *fileStat; //definition of struct
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
这是无效代码。您创建了一个不指向任何地方的指针。它需要指向一个统计实例。像这样
struct stat other_stat;
struct stat *fileStat; //definition of struct
fileStat = &other_stat; // make it point at the instance we just made
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
或者在堆上创建一个
struct stat *fileStat = (struct stat*)malloc(sizeof(struct stat));
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
在您的 'second notation' 示例中,一旦您这样做了
stat("filename", fileStat)
所有的赌注都落空了。 Stat 已将数据写入未指定的位置。这导致 'Undefined Behavior'。您可能很幸运,可以写入无法写入的位置。在这种情况下,您的程序将立即中止。为什么这么幸运?好吧,您会知道出了什么问题。最糟糕的行为是您最终写入了一个可写的位置,并且目前没有被用于其他任何地方。您的程序将运行并且您将发布它,然后客户使用具有更长文件名的文件或在 OS 升级后或在具有不同内存量的机器上尝试它并且 'boom' 它给出奇怪的答案或死亡。这就是 Java、c#、go 等语言存在的原因。以免惹上麻烦
我遇到 this post 讨论如何从 stat
库打印文件权限,但我对结构的定义如何工作感到困惑。
当我定义结构时,我总是像 struct struct_type *name
那样定义它们。但在示例中,结构定义为 struct struct_type name
(不是指针)。据我所知,根据您定义结构的方式,应该有两种不同的方式来访问信息。
选项一表示法
struct stat fileStat; //definition of struct
stat("<filename>", &fileStat); //execute the stat function
fileStat.member_name; //access a member of a struct
选项二表示法
struct stat *fileStat; //definition of struct
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
但是当我将所提供示例中的选项一符号切换为选项二时,我得到了非常不同的结果。这两个选项有什么不同?它不是在有效地做同样的事情吗?
示例代码
选项一符号程序
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
struct stat fileStat;
stat("main", &fileStat);
printf("Information for %s\n", argv[1]);
printf("---------------------------\n");
printf("File Size: \t\t%lld bytes\n", fileStat.st_size);
printf("Number of Links: \t%d\n", fileStat.st_nlink);
printf("File inode: \t\t%llu\n", fileStat.st_ino);
printf("File Permissions: \t");
printf( (S_ISDIR(fileStat.st_mode)) ? "d" : "-");
printf( (fileStat.st_mode & S_IRUSR) ? "r" : "-");
printf( (fileStat.st_mode & S_IWUSR) ? "w" : "-");
printf( (fileStat.st_mode & S_IXUSR) ? "x" : "-");
printf( (fileStat.st_mode & S_IRGRP) ? "r" : "-");
printf( (fileStat.st_mode & S_IWGRP) ? "w" : "-");
printf( (fileStat.st_mode & S_IXGRP) ? "x" : "-");
printf( (fileStat.st_mode & S_IROTH) ? "r" : "-");
printf( (fileStat.st_mode & S_IWOTH) ? "w" : "-");
printf( (fileStat.st_mode & S_IXOTH) ? "x" : "-");
printf("\n\n");
printf("The file %s a symbolic link\n", (S_ISLNK(fileStat.st_mode)) ? "is" : "is not");
return 0;
}
选项一符号输出
Information for (null)
---------------------------
File Size: 49960 bytes
Number of Links: 1
File inode: 58527531
File Permissions: -rwxr-xr-x
The file is not a symbolic link
选项二符号程序
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc, char **argv)
{
struct stat *fileStat;
stat("main", fileStat);
printf("Information for %s\n", argv[1]);
printf("---------------------------\n");
printf("File Size: \t\t%lld bytes\n", fileStat->st_size);
printf("Number of Links: \t%d\n", fileStat->st_nlink);
printf("File inode: \t\t%llu\n", fileStat->st_ino);
printf("File Permissions: \t");
printf( (S_ISDIR(fileStat->st_mode)) ? "d" : "-");
printf( (fileStat->st_mode & S_IRUSR) ? "r" : "-");
printf( (fileStat->st_mode & S_IWUSR) ? "w" : "-");
printf( (fileStat->st_mode & S_IXUSR) ? "x" : "-");
printf( (fileStat->st_mode & S_IRGRP) ? "r" : "-");
printf( (fileStat->st_mode & S_IWGRP) ? "w" : "-");
printf( (fileStat->st_mode & S_IXGRP) ? "x" : "-");
printf( (fileStat->st_mode & S_IROTH) ? "r" : "-");
printf( (fileStat->st_mode & S_IWOTH) ? "w" : "-");
printf( (fileStat->st_mode & S_IXOTH) ? "x" : "-");
printf("\n\n");
printf("The file %s a symbolic link\n", (S_ISLNK(fileStat->st_mode)) ? "is" : "is not");
return 0;
}
选项二符号输出
Information for (null)
---------------------------
File Size: 5193343115435036343 bytes
Number of Links: 12487
File inode: 930377443599221576
File Permissions: -r-x--x---
The file is not a symbolic link
这不是替代符号
struct stat *fileStat; //definition of struct
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
这是无效代码。您创建了一个不指向任何地方的指针。它需要指向一个统计实例。像这样
struct stat other_stat;
struct stat *fileStat; //definition of struct
fileStat = &other_stat; // make it point at the instance we just made
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
或者在堆上创建一个
struct stat *fileStat = (struct stat*)malloc(sizeof(struct stat));
stat("<filename>", fileStat); //execute the stat function
fileStat->member_name; //access a member of a struct
在您的 'second notation' 示例中,一旦您这样做了
stat("filename", fileStat)
所有的赌注都落空了。 Stat 已将数据写入未指定的位置。这导致 'Undefined Behavior'。您可能很幸运,可以写入无法写入的位置。在这种情况下,您的程序将立即中止。为什么这么幸运?好吧,您会知道出了什么问题。最糟糕的行为是您最终写入了一个可写的位置,并且目前没有被用于其他任何地方。您的程序将运行并且您将发布它,然后客户使用具有更长文件名的文件或在 OS 升级后或在具有不同内存量的机器上尝试它并且 'boom' 它给出奇怪的答案或死亡。这就是 Java、c#、go 等语言存在的原因。以免惹上麻烦