在 C 中声明指针的顺序真的很重要吗? getcwd() 问题

发布于 2024-08-28 11:10:34 字数 529 浏览 15 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

捂风挽笑 2024-09-04 11:10:34

以下来自 getcwd(3)

DESCRIPTION
     The getcwd() function copies the absolute pathname of the current working
     directory into the memory referenced by buf and returns a pointer to buf.
     The size argument is the size, in bytes, of the array referenced by buf.

     If buf is NULL, space is allocated as necessary to store the pathname.
     This space may later be free(3)'d.

即将 buf 设置为 NULLfree(3) <完成后,代码>目录; 或者自己为buf分配空间(因为您告诉getcwd(3)您那里有1K)。

编辑:

所以要清理它一点,它是:

char *dir = getcwd( NULL, 0 );

if ( dir == NULL ) { /* handle error */ }
/* use dir */
free( dir );

char buf[1024]; /* or allocate it with malloc(3) */

if ( getcwd( buf, 1024 ) == NULL ) { /* handle error */ }

/* use buf, DO NOT free it if it's on the stack or static, 
   only if malloc-ed */

Here's from getcwd(3):

DESCRIPTION
     The getcwd() function copies the absolute pathname of the current working
     directory into the memory referenced by buf and returns a pointer to buf.
     The size argument is the size, in bytes, of the array referenced by buf.

     If buf is NULL, space is allocated as necessary to store the pathname.
     This space may later be free(3)'d.

That is - set the buf to NULL and free(3) the dir when done; OR allocate space for the buf yourself (since you are telling the getcwd(3) you have 1K there).

Edit:

So to clean it up a bit, it's either:

char *dir = getcwd( NULL, 0 );

if ( dir == NULL ) { /* handle error */ }
/* use dir */
free( dir );

or

char buf[1024]; /* or allocate it with malloc(3) */

if ( getcwd( buf, 1024 ) == NULL ) { /* handle error */ }

/* use buf, DO NOT free it if it's on the stack or static, 
   only if malloc-ed */
陪你到最终 2024-09-04 11:10:34

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 using malloc() -- you would then free this using free() 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 by getcwd() 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.

好久不见√ 2024-09-04 11:10:34

您只声明了一个指针,没有为 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.

聚集的泪 2024-09-04 11:10:34

您声明指针的顺序将决定它们在内存中堆栈上的放置顺序。我的猜测是,从 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 trashing dir in example one but not two. You're other OS may be preventing this bug silently or handling it differently some how.

过期以后 2024-09-04 11:10:34

声明的顺序并不重要。

char *getcwd(char *buf, size_t size);  

The getcwd() function copies an absolute pathname of the current working 
directory to the array pointed to by **buf**, which is of length **size**.

buf 在使用它之前应该分配内存。

buf = malloc(length * sizeof(char));

执行 char *buf; 后,buf 包含垃圾值,并且当 getcwd() 尝试修改 bu buf 指向的内存时,它会导致分段错误

Order of declaration does not matter.

char *getcwd(char *buf, size_t size);  

The getcwd() function copies an absolute pathname of the current working 
directory to the array pointed to by **buf**, which is of length **size**.

buf should be allocated memory before using it.

buf = malloc(length * sizeof(char));

After char *buf; is executed, buf contains garbage-value and when getcwd() tries to modify the memory pointed bu buf, it causes Segmentation Fault.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文