1

I received a double free or corruption (fasttop) on the code below. Can't seem to figure out which pointer is creating this error. It looks like the error is being produced in the while loop of the echo_cnt function. Thanks!

    static void init_echo_cnt(void) {

        sem_init(&mutex, 0, 1);
        byte_cnt = 0;

    }

    void echo_cnt(int connfd) {
        int n;

        FILE *fp = fopen("words.txt", "r");
        static pthread_once_t once = PTHREAD_ONCE_INIT;
        pthread_once(&once, init_echo_cnt);
        char *buf = calloc(MAXLINE, sizeof(char));

        while((n=readLine(connfd, buf, MAXLINE)) != 0) {
        char *str = fgets(buf, sizeof buf, fp);
            char *token;
            token = strtok(str, " ");
        char *result = malloc(strlen(token +64));
            while (token != NULL){
            printf("In the while loop\n");
                if (spellcheck(token, fp)==1){
                    strcat(result, token);
                    strcat(result, "OK");
                }
                else{
                    strcat(result, "MISPELLED");
                }
                ssize_t kick =  write(connfd, result, MAXLINE); 

                free(result); } 

        }
            close(connfd);
    }

    void *thread(void *vargp) {
      int connfd;
      pthread_detach(pthread_self());
      printf("World\n");

      while(1) {

        connfd=sbuf_remove(sbuf); //remove socket
        echo_cnt(connfd); //service client

      }
    close(connfd); //close socket
    }
Chris
  • 29
  • 1
  • 1
    Since `buf` is a pointer, `sizeof buf` will give you the size *of the pointer*, not the data it points to. Since you always allocate a fixed compile-time specified amount of memory, why not make `buf` an array? You also never `free` the memory allocated for `buf`, leading to a memory leak. – Some programmer dude Nov 12 '17 at 03:00
  • 1
    As for a possible cause of your problem, there are two alternatives: The first is that `strlen(token +64)` does not give you the length of `token` plus 64. What you do is basically pass `&token[64]` as the pointer to `strlen`. The second possible problem is that `malloc` does not initialize the memory it allocates, and then you use `strcat` with that memory as destination, which means `strcat` will iterate over the *indeterminate* contents to find the terminator (which it might not find at all, or beyond the end of the allocated memory). – Some programmer dude Nov 12 '17 at 03:03
  • 1
    You might like to read this: [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – alk Nov 12 '17 at 10:00
  • for ease of readability and understanding: 1) consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces, not a mixture of spaces and tabs. 2) separate code blocks (for, if, else, while, do...while, switch, case, default) via a single blank line. – user3629249 Nov 14 '17 at 02:25
  • when calling `write()`, after obtaining the returned value, check that value for errors, etc. – user3629249 Nov 14 '17 at 02:25
  • when calling `strtok()`, check (!=NULL) the result immediately, do not use the returned value until after checking – user3629249 Nov 14 '17 at 02:27
  • when calling any of the heap allocation functions: (malloc, calloc, realloc) 1) always check(!=NULL) the returned value to assure the operation was successful. – user3629249 Nov 14 '17 at 02:32
  • the array `sbuf[]` is not declared in the posted code. the function: `sbuf_remove()` is not posted. the function: `spellcheck()` is not posted. – user3629249 Nov 14 '17 at 02:37
  • when calling `fgets()`, always check the returned value to assure the operation was successful. – user3629249 Nov 14 '17 at 02:38
  • regarding: `char *str = fgets(buf, sizeof buf, fp);` the variable `buf` is a pointer. the result of applying `sizeof()` will be 8 or 4 or 2 depending on the underlying hardware architecture.' – user3629249 Nov 14 '17 at 02:40
  • regarding: `char *result = malloc(strlen(token +64));` this will find the length of the char array that is token + 64 more bytes into memory. Probably NOT what you want. Perhaps you meant: `char *result = malloc(strlen(token) +64); – user3629249 Nov 14 '17 at 02:41
  • the function: `readLine()` is not in the posted code and can be easily confused with the system function: `readline()` – user3629249 Nov 14 '17 at 02:44
  • when calling `fopen()`, always check (!=NULL) the returned value to assure the operation was successful. If not successful, call `perror()` so an appropriate error message AND the text from the system on why the system thinks the function failed are output to `stderr`. – user3629249 Nov 14 '17 at 02:47
  • why would some function called: `spellcheck()` need a parameter to the file where the original char string to check came from? – user3629249 Nov 14 '17 at 02:50
  • the function: `fgets()` includes the trailing newline in the target buffer. The posted code (IMO) should be removing the newline. perhaps by something like: `char *newline; if( NULL != (newline = strchr( buf, '\n' ) ) { *newline = '\0'; }` – user3629249 Nov 14 '17 at 02:55
  • the posted code contains a massive memory leak. the pointer, returned from `calloc()` or `malloc()` before exiting the function, needs to call `free()` with the pointer as a parameter. – user3629249 Nov 14 '17 at 02:57
  • please post a [mvce]. The posted code is missing a lot, so it not compilableable, and contains a lot of superfluous code about a semaphore and about a thread function. – user3629249 Nov 14 '17 at 03:03
  • Possible duplicate of [How to track down a "double free or corruption" error](https://stackoverflow.com/questions/2902064/how-to-track-down-a-double-free-or-corruption-error) – Raedwald Dec 06 '18 at 13:27

1 Answers1

0

I am only checking the section where you think the error is and I see that you get the token the first time, and never grab another token while in the loop. Just grab another token inside the while loop.

For example:

    /* get the first token */
   token = strtok(str, s);

   /* walk through other tokens */
   while( token != NULL ) {
      printf( " %s\n", token );

      token = strtok(NULL, s);
   }

This example was taken from: https://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm