Search code examples
cstringsegmentation-faultfgets

Dealing with strings in C


I'm trying to write a stream editor in C and I'm having a hard time dealing with strings. After reading in the lines of a File, I want to store them locally in an array of Strings. However, when I try to store the variable temp into the array of strings StoredEdits I get a segmentation fault (core dumped) error. Furthermore, if I uncomment the char* temp2 variable and save this into my array as a workaround, then the last value read in gets stored for every value in the array.

I assume this has to do with the fact that temp2 is a pointer. I've tried a million things like malloc'ing and free'ing this variable after each iteration, but nothing seems to work.

Any help would be greatly appreciated.

      #define MAX_SIZE 100 
      typedef char String[MAX_SIZE];   
          int main(int argc, char* argv[]){
              char** StoredEdits;                                                                                                                                                                    
              int index, numOfEdits;
              FILE *EditFile;                                                                                                                                                                                       
              char* temp;
              //char* temp2;                                                                                                                                                                                            

              StoredEdits = (char**)malloc(MAX_INPUT_SIZE*sizeof(String));                                                                                                                                           

              /*Check to see that edit file is passed in.*/
              if(argc < 2){
                printf("ERROR: Edit File not given\n");
                return(EXIT_FAILURE);
              }

              printf("%s\n",argv[1]);

              if( (EditFile = fopen(argv[1],"r")) != NULL ){
                printf("file opened\n");
                numOfEdits = 0;
                while(fgets(temp, MAX_STRING_SIZE, EditFile) != NULL){
                  printf("%d %s",numOfEdits,temp);
                  //temp2 = temp;                                                                                                                                                                                       
                  StoredEdits[numOfEdits++] = temp;
                  //StoredEdits[numOfEdits++] = temp;
                  printf("Stored successfully\n");
                }

..........

              printf("%d\n",numOfEdits);
              for(index=0;index<numOfEdits;index++){
                printf("%d %s\n",index, StoredEdits[index]);
              }

Solution

  • You need to initialize temp to point to valid storage.

    temp = malloc(MAX_STRING_SIZE+1);
    

    It looks like you may have intended to do something like this:

    String temp;
    

    using your macro. This would be better as a regular char array. And the common name for this is buffer.

    char buffer[MAX_STRING_SIZE+1];
    

    Then, you should store in your array, not temp itself, but a new string containing a copy of the contents. There is a POSIX function strdup that should be helpful here. Note, strdup is not part of the C standard, but it is available in most hosted implementations. Historically, it comes from the BSD branch.

    StoredEdits[numOfEdits++] = strdup(temp);
    

    Let me backpedal a little and say that if you're allocating new storage for temp inside the loop, then you should skip the strdup because, as Jim Balter says, this will leak memory. If you allocate temp outside of the loop, then it makes little difference whether you allocate it statically (by declaring a char []) or dynamically (with malloc).


    By the way, this line will not buy you much:

    typedef char String[MAX_SIZE];
    

    For why, see the classic Kernighan (the K in K&R) essay Why Pascal is not my favorite Programming Language.


    Also note, that my examples above do not check the pointer returned by malloc. malloc can fail. When malloc fails it will return a NULL pointer. If you try to store data through this pointer, Kaboom!