在 C 中声明指针的顺序真的很重要吗? getcwd() 问题
在 Solaris 5.8 机器上,我有以下代码:
[non-working code]
char *buf;
char *dir;
size_t psize;
psize = (size_t) 1024;
dir = getcwd(buf, psize);
在这台 UNIX 机器上,上面的代码不起作用,并且在尝试时出现分段错误运行程序。仅当我声明 dir
before buf
:
[working code]
char *dir;
char *buf;
...
dir = getcwd(buf, psize);
当使用另一种风格的 Unix 时,它才有效,例如作为 Mac OS X,我没有得到任何关于如何编写代码的似乎非常严格的规则。谁能解释一下上面的例子是怎么回事?谢谢!
On a Solaris 5.8 machine, I have the following code:
[non-working code]
char *buf;
char *dir;
size_t psize;
psize = (size_t) 1024;
dir = getcwd(buf, psize);
On this unix machine, the above does not work and I get a segmentation fault when trying to run the program. It only works if I declare dir
before buf
:
[working code]
char *dir;
char *buf;
...
dir = getcwd(buf, psize);
When using another flavor of Unix, such as Mac OS X, I don't get any of these what seem to be very strict rules on how to write the code. Can anyone explain what's going on with the above example? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
以下来自
getcwd(3)
:即将
buf
设置为NULL
并free(3)
<完成后,代码>目录; 或者自己为buf
分配空间(因为您告诉getcwd(3)
您那里有1K)。编辑:
所以要清理它一点,它是:
或
Here's from
getcwd(3)
:That is - set the
buf
toNULL
andfree(3)
thedir
when done; OR allocate space for thebuf
yourself (since you are telling thegetcwd(3)
you have 1K there).Edit:
So to clean it up a bit, it's either:
or
POSIX 要求第一个参数是指向缓冲区的指针,其中路径名被存储。 Mac OS X、Linux、Solaris 和其他操作系统上存在的一个常见扩展是,如果第一个参数为 NULL,则 getcwd() 将使用 malloc() 为您分配一个缓冲区。 )——当你使用完它后,你可以使用
free()
释放它。 POSIX 允许此扩展,但不是必需的,因此您不应在可移植代码中依赖它。在您的情况下,您将未初始化的值作为第一个参数传递给
getcwd()
。如果它恰好等于 NULL,则将分配一个缓冲区;如果它是其他无效指针,那么您可能会遇到分段错误。由于该值未初始化,因此它可以具有任何值,并且可能取决于声明的顺序。如果您打算通过 getcwd() 分配缓冲区,则显式传入 NULL 值;没有必要为此声明一个变量。然而,更可移植的解决方案是将指针传递给您自己的缓冲区,而不是依赖此扩展。POSIX requires the first argument to be a pointer to a buffer in which the path name is stored. A common extension, which is present on Mac OS X, Linux, Solaris, and others, is that if the first argument is NULL then
getcwd()
will allocate a buffer for you usingmalloc()
-- you would then free this usingfree()
when you are done with it. This extension is allowed by POSIX but not required, so you should not depend on it in portable code.In your case, you are passing an uninitialized value as the first argument to
getcwd()
. If it happens to be equal to NULL then a buffer would be allocated; if it is some other invalid pointer then you may get a segmentation fault. Since the value is uninitialized it could have any value, and could depend on the order of declaration. If you intended for a buffer to be allocated bygetcwd()
then pass in the value NULL explicitly; it is not necessary to declare a variable for this. However a more portable solution would be to pass in a pointer to your own buffer rather than relying on this extension.您只声明了一个指针,没有为 getcwd 分配任何内存来写入。 getcwd 不会为您分配内存。需要自己调用malloc来分配。
You only declared a pointer, you didn't allocate any memory for getcwd to write into. getcwd doesn't allocate the memory for you. You need to call malloc to allocate it yourself.
您声明指针的顺序将决定它们在内存中堆栈上的放置顺序。我的猜测是,从
buf
地址开始存在缓冲区溢出,在示例一(但不是示例二)中,它破坏了dir
。您的其他操作系统可能会默默地阻止此错误或以某种方式以不同的方式处理它。The order you declare the pointers on will determine the order they are placed on the stack in memory. My guess is that there is a buffer overrun starting at the address of
buf
which is trashingdir
in example one but not two. You're other OS may be preventing this bug silently or handling it differently some how.声明的顺序并不重要。
buf
在使用它之前应该分配内存。执行
char *buf;
后,buf
包含垃圾值,并且当getcwd()
尝试修改 bubuf 指向的内存时
,它会导致分段错误
。Order of declaration does not matter.
buf
should be allocated memory before using it.After
char *buf;
is executed,buf
contains garbage-value and whengetcwd()
tries to modify the memory pointed bubuf
, it causesSegmentation Fault
.