1
votes

I was trying to make reading of input from stdin with dynamic allocation in two different ways:

1) I read from stdin, malloc, realloc and write into array in main. Then when I printf those elements of array, everything is ok.

2) I declare global variable in main, then I throw it into function in which I read from stdin, malloc, realloc and write into that array. When I printf these elements in the function, it works fine but when I do that outside of function, it gives me Segmentation fault.

Can you check these codes and help me how to solve this problem?

2)

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

/*--------------------------------------------------------------------------*/

void nacitaj( int *pocet_slov, char **slovnik ){

  char buffer[60];
  int size = 60;

  while( fgets( buffer, size, stdin ) != NULL ){
      *pocet_slov = *pocet_slov + 1;
      slovnik = (char**) realloc( slovnik, (*pocet_slov+1) * sizeof(char*) );
      slovnik[*pocet_slov-1] = (char*) malloc( strlen(buffer) * sizeof(char) );
      buffer[strlen(buffer)-1] = '\0';
      strcpy( slovnik[*pocet_slov-1], buffer );
  }

  for( int i = 0; i < *pocet_slov; i ++ ){
      printf( "%d. %s\n", i+1, slovnik[i] );
  } 
}

/*---------------------------------------------------------------------------*/

int main(){
  char **slovnik = NULL;

  int pocet_slov = 0;

  int i;

  printf( "Zadavaj slova do slovniku:\n" );
  nacitaj( &pocet_slov, slovnik );

  for( i = 0; i < pocet_slov; i ++ ){
      printf( "%d. %s\n", i+1, slovnik[i] );
  }

  return 0;
}

1)

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

int main(){
  char **slovnik = NULL;

  int pocet_slov = 0;

  char buffer[60];
  int size = 60;    
  int i;

  printf( "Zadavaj slova do slovniku:\n" );

  while( fgets( buffer, size, stdin ) != NULL ){
      pocet_slov ++;
      slovnik = (char**) realloc( slovnik, (pocet_slov+1) * sizeof(char*) );
      slovnik[pocet_slov-1] = (char*) malloc( strlen(buffer) * sizeof(char) );
      buffer[strlen(buffer)-1] = '\0';
      strcpy( slovnik[pocet_slov-1], buffer );
  }

  for( i = 0; i < pocet_slov; i ++ ){
      printf( "%d. %s\n", i+1, slovnik[i] );
  } 

  return 0;
}

Example of input:

car
bird
pen
2
My input are words that are "imported" into vocabulary.. so for example: car\nbird\npenalik33
I mean specifically. What is the exact input to program 2) that caused it to segfault? And please update your question with this info.dbush
for example those words... you can put there any word, press enter and then ctrl-D(EOF)alik33
@alik33 please update your question and state exactly what your input is.Jabberwocky

2 Answers

2
votes

You should be passing the address of slovnik to your nacitaj function. Otherwise, updates to the variable in nacitaj are not visible in main.

Also, always remember to free any dynamically allocated memory.

void nacitaj( int *pocet_slov, char ***slovnik ){

  char buffer[60];
  int size = 60;

  while( fgets( buffer, size, stdin ) != NULL ){
      *pocet_slov = *pocet_slov + 1; 
      // dereference slovnik to update the variable in main
      // don't cast the return value of malloc or realloc
      *slovnik = realloc( *slovnik, (*pocet_slov+1) * sizeof(char*) );
      (*slovnik)[*pocet_slov-1] = (char*) malloc( strlen(buffer) * sizeof(char) );
      buffer[strlen(buffer)-1] = '\0';
      strcpy( (*slovnik)[*pocet_slov-1], buffer );
  }

  for( int i = 0; i < *pocet_slov; i ++ ){
      printf( "%d. %s\n", i+1, (*slovnik)[i] );
  }
}

int main(){
  char **slovnik = NULL;

  int pocet_slov = 0;

  int i;

  printf( "Zadavaj slova do slovniku:\n" );
  // pass the address of slovnik 
  nacitaj( &pocet_slov, &slovnik );   

  for( i = 0; i < pocet_slov; i ++ ){
      printf( "%d. %s\n", i+1, slovnik[i] );
  }

  // free the allocated memory
  for( i = 0; i < pocet_slov; i ++ ){
      free(slovnik[i]);
  }
  free(slovnik);

  return 0;
}
-1
votes

In the code number 2) you are not declaring a global variable. You should declare your global variable before main scope, example:

#include <stdio.h>

static int shared = 3;

void add(void){
     shared++;
}

int main(void){
     printf("%d", shared)// will print 3
     add();
     printf("%d", shared)// will print 4

     return 0;
}

This is just an example to achieve what you want, for education purpose only. You should be very carefully about global variables.