Is the order I declare pointers really matters in C? Getcwd () problem

On a Solaris 5.8 machine, I have the following code:

[inoperative code]

char *buf; char *dir; size_t psize; psize = (size_t) 1024; dir = getcwd(buf, psize); 

On this machine, unix does not work above, and I get a segmentation error when I try 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 a different flavor of Unix, such as Mac OS X, I do not get any of them that seem to be very strict rules for writing code. Can someone explain what is happening with the above example? Thanks!

+4
source share
5 answers

Here 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 - when dir NULL and free(3) dir set; OR make space for buf yourself (since you tell getcwd(3) , you have 1K there).

Edit:

So, to clean it up a bit, this is 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 on the stack or static, only if malloc-ed */ 
+6
source

POSIX requires that the first argument be a pointer to a buffer in which the path name is stored. The general extension that 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() - then you will free it using free() when you are done with it. This extension is allowed by POSIX, but is not required, so you should not depend on it in portable code.

In your case, you pass an uninitialized value as the first argument to getcwd() . If it is NULL, then a buffer will be allocated; if this is some other invalid pointer, then you might get a segmentation error. Since the value is uninitialized, it can have any value and may depend on the order of declaration. If you were intended to allocate the getcwd() buffer, then explicitly enter NULL; there is no need to declare a variable for this. However, a more portable solution would be to pass a pointer to its own buffer, rather than relying on this extension.

+4
source

You just declared a pointer, you did not allocate memory for getcwd for writing. getcwd does not allocate memory for you. You need to call malloc to select it yourself.

+3
source

The order in which you specify the pointers will determine the order in which they are placed on the stack in memory. I assume that the buffer overflow begins with the address buf , which splits the dir in the example one, but not two. You are a different OS, it can prevent this error silently or handle it differently in some way.

+2
source

Ordering an ad 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 must be allocated memory before using it.

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

After executing char *buf; buf contains the garbage value and when getcwd() tries to change the allocated bu buf memory, it calls Segmentation Fault .

+2
source

Source: https://habr.com/ru/post/1306638/


All Articles