Why Does This Program Cause a Segmentation Fault?

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
11 replies · 3K views
gruba
Messages
203
Reaction score
1

Homework Statement


Write a program that reads strings(words) from a text file and copy the inverted words to another file (use the command line arguments). Form a new array of words b from original array a using the function
void formNewArray(char **a, char **b, int n, char* (*t)(char *));
where n is the number of words in array, and (*t) is the pointer to function for inverting a string.

Homework Equations


-File handling
-Pointers

The Attempt at a Solution


The following program gives SIGSEGV segmentation fault in function formNewArray():
Code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void form_temp_array(char **a,char **b,int n,char* (*t)(char *))
{
  int i;
  for(i=0 ;i<n; i++)
  b[i]=(*t)(a[i]);
}

char* reverseWord(char *word)
{
  char *new_word;
  new_word=(char*)malloc(sizeof(strlen(word+1)));
  new_word=strrev(word);
  return new_word;
}

void print(char **arr,int n)
{
  int i;
  for(i=0; i<n; i++)
  printf("%s\n",arr[i]);
}

int main()
{
  char* a[]={"PROGRAMMING","CODING"};
  int n=sizeof(a)/sizeof(char**);
  char* b[n];
  printf("original words:\n");
  print(a,n);
  printf("reversed words:\n");
  form_temp_array(a,b,n,&reverseWord);
  print(b,n);
  free(reverseWord);
  return 0;
}
 
Last edited:
on Phys.org
rcgldr said:
In reverseWord(), allocate memory for new word

Code:
    char *new_word = malloc(strlen(word)+1);

In form_temp_array, just assign to b:

Code:
    b[i] =(*t)(a[i]));

rcgldr said:
In reverseWord(), allocate memory for new word

Code:
    char *new_word = malloc(strlen(word)+1);

In form_temp_array, just assign to b:

Code:
    b[i] =(*t)(a[i]));
 
Trying to edit my answer had problems so I deleted it. You can delete your prior post also if you want. The issue is in main: char *a[] points to literal strings, so they can't be reversed, as they could be in write-protected memory. Rather than allocate memory, copy, and reverse in reverseWord(), I thought it would be better to change main(), and allocate memory for each pointer in a and make copies of the literal strings. I used w[] as an array of pointers to the literal strings.

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

void form_temp_array(char **a,char **b,int n,char* (*t)(char *))
{
    int i;
    for(i=0 ;i<n; i++)
        b[i] = (*t)(a[i]);
}

char* reverseWord(char *word)
{
    return strrev(word);         /* or _strrev, depending on compiler */
}

void print(char **arr,int n)
{
    int i;
    for(i=0; i<n; i++)
        printf("%s\n",arr[i]);
}

int main()
{
    int i;
    char* w[]={"PROGRAMMING","CODING"};
    int n = sizeof(w)/sizeof(char**);
    char* a[n];          /* or    char** a = _alloca(n*sizeof(char*)); */
    char* b[n];          /* or    char** b = _alloca(n*sizeof(char*)); */
    for(i = 0; i < n; i++){
        a[i] = malloc(strlen(w[i])+1);
        strcpy(a[i], w[i]);
    }
    printf("original words:\n");
    print(a,n);
    form_temp_array(a,b,n,reverseWord);
    printf("reversed words:\n");
    print(b,n);
    for(i = 0; i < n; i++)
        free(a[i]);
    return 0;
}
 
Last edited:
  • Like
Likes   Reactions: gruba
I have updated the code, and there is still an error.
Also, I don't think that you can use operator = for string manipulation.
 
I updated my previous answer to show working code. The issue was that a pointed to literals, so I used an array called w, then in a, I allocated memory and copied the literal strings.
 
Several problems, the main being:
  • char *new_word = _strrev(word);
    return new_word;
The new_word pointer is a local variable in reverseWord and is not available outside that function (it is allocated on the stack and deallocated when the function returns).
 
Svein said:
Several problems, the main being:
  • char *new_word = _strrev(word);
    return new_word;
The new_word pointer is a local variable in reverseWord and is not available outside that function (it is allocated on the stack and deallocated when the function returns).
It doesn't matter, since what is being returned is the pointer to the string from strrev(), not a reference to new_word. Since strrev reverses in place, there's no point in using the returned value, but since it does return the pointer to word, the code can be simplfied to:

Code:
char* reverseWord(char *word)
{
    return strrev(word);
}
 
Last edited:
Svein said:
Several problems, the main being:
  • char *new_word = _strrev(word);
    return new_word;
The new_word pointer is a local variable in reverseWord and is not available outside that function (it is allocated on the stack and deallocated when the function returns).

That would be a problem if the function were returning a pointer to new_word. But it is returning the value. That value will be copied somewhere so it doesn't matter that new_word is lost.
 
rcgldr said:
It doesn't matter, since what is being returned is the pointer to the string from strrev(), not a reference to new_word. Since strrev reverses in place, there's no point in using the returned value, but since it does return the pointer to word, the code can be simplfied to:

Code:
char* reverseWord(char *word)
{
    return strrev(word);
}

It can be simplified further by having no reverseWord at all and simply passing a pointer to strrev as an argument.
 
Hornbein said:
It can be simplified further by having no reverseWord at all and simply passing a pointer to strrev as an argument.
True, that would be better still. I wasn't sure if it would be OK to use a pointer to a library function for this class assignment. So in main(), it would be:

Code:
    form_temp_array(a,b,n,strrev);
 
Assume that file1 contains original words, and is the first argument of a command line.
How to read the content of file1 and put the inverses to file2, which is the second argument of a command line?
 
Thanks for all your help, I have figured out how to do file manipulation.