Home > Back-end >  Function works in windows but doesn't in linux
Function works in windows but doesn't in linux

Time:07-08

I've been learning C for like 5 days, and so I tried doing some little projects. I created a very simple library that automates getting a string from the user,then implemented it in a program which just outputs the string's value.

It runs perfectly on Windows (Compiled through MSVC: 'cl .\main.c /link .\get_string\m_string.obj') but it doesn't in Linux (Compiled with gcc using : 'gcc -o test main.c m_string.o')

I know that MAX being 1024 makes absolutely no sense, it's just a test value.

//main.c
#include <stdio.h>
#include "get_string/m_string.h"

int main(int argc, char *argv[])
{
  char *inputf = get_string("Something: ");
  printf("%s", inputf);
  return 0;
}
// m_string.h
#include <stdio.h>
#define MAX 1024
char *get_string(char *prompt);
//m_string.c
#include "m_string.h"
char *get_string(char *prompt)
{
  char *s[MAX]; 
  printf("%s", prompt);
  fgets(s, MAX, stdin);
  return s;
}

Running main.c on Windows works as expected:

Something: something
something

Running main.c on Linux:

Something: something
(null)$

Since I am using a very big value for the maximum memory used in fgets(), I don't think that a buffer overflow is the cause (Would have probably gotten Segmentation Fault otherwise).

Thank you for reading and I hope someone can shed some light on the matter for an absolute beginer like me.

CodePudding user response:

  1. char *s[MAX]; creates an array of MAX pointers, not char values.

    ALWAYS enable your compiler's warnings. It would have found this. With gcc, I use -Wall -Wextra -pedantic.

  2. get_string returns a pointer to a variable that no longer exists once get_string returns.

    One way to solve this is to allocate a buffer using malloc, and free that buffer in the caller.

#include <stdio.h>
#include <stdlib.h>

#define MAX 1024

char *get_string( const char *prompt ) {
   char *s = malloc( MAX );
   if ( !s )
      return NULL;

   printf( "%s", prompt );

   if ( !fgets( s, MAX, stdin ) ) {
      free( s );
      return NULL;
   }

   return s;
}

int main( void ) {
  char *inputf = get_string( "Something: " );
  if ( !inputf ) {
     perror( NULL );
     exit( 1 );
  }

  printf( "%s", inputf );

  free( inputf );

  return 0;
}

Demo on Compiler Explorer

CodePudding user response:

It really does not run "correctly", because this is undefined behavior. You may not access temporary storage outside of the scope in which it was defined.

In addition to this, you also have a type error: char *s[MAX]; defines an array of MAX char pointers. Using this as a string buffer should not have been allowed past the compiler.

If you do not want to allocate memory dynamically for this, then make the string buffer static. You can even make it thread-local (since C11) if for some reason you plan to use this function in concurrent environments.

#include <stdio.h>

#define MAX 1024

char *get_string(const char *prompt)
{
  static _Thread_local char s[MAX];
  printf("%s", prompt);

  if (!fgets(s, MAX, stdin)) {
      s[0] = '\0';
  }

  return s;

}

int main(int argc, char *argv[])
{
  char *inputf = get_string("Something: ");
  printf("%s", inputf);
  return 0;
}
  • Related