-4

In my program, i am allocating dyanamic memory to a variable buffer of type 'char *' using malloc. Then if I using strtok(buffer,"+"); it is giving Segmentation fault. I got the reason for this Stackoverflow and same problem Stackoverflow. but neither post giving me a desired solution. As I can't use static memory or array type according to my program. My problem is In strtok, in arguements if I use char array then working properly and when use char * then give error. How to use char * in strtok arguements.

char *buffer;
int len;
connection_t * conn;
long addr = 0;
FILE *fptr;

if (!ptr) pthread_exit(0);
conn = (connection_t *)ptr;
const char *s = "+";
char *token;


/* read length of message */
read(conn->sock, &len, sizeof(int));
if (len > 0)
{

addr = (long)((struct sockaddr_in *)&conn->address)->sin_addr.s_addr;
buffer = (char *)malloc((len+1)*sizeof(char));
buffer[len] = 0;
/* read message */
read(conn->sock, buffer, len);
printf("%s and %d \n",buffer, addr);
/* get the first token */
token = strtok(buffer,"+");

last line showing segmentation fault

Community
  • 1
  • 1
piyush-balwani
  • 524
  • 3
  • 15
  • 3
    Please show the code.,.... – Sourav Ghosh Jan 16 '16 at 15:46
  • 1
    You need to read [ask] – Amit Jan 16 '16 at 15:47
  • char *buffer; char *token; buffer = (char *)malloc((len+1)*sizeof(char)); buffer[len] = 0; token = strtok(buffer,"+"); showing segmentation fault, but if i use buffer[]="a+b+c"; then it is working. How Can I use char * type arguement in strtok. – piyush-balwani Jan 16 '16 at 15:52
  • [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Jan 16 '16 at 15:56
  • `strcpy(buffer, source_string);` before `strtok(buffer,"+");` – BLUEPIXY Jan 16 '16 at 16:04
  • 2
    You forgot to fill `buffer` with data before `strtok`ing it. – Spikatrix Jan 16 '16 at 16:22
  • i recieved data in buffer through read(conn->sock, buffer, len);. – piyush-balwani Jan 16 '16 at 16:55
  • the array pointer that the first argument of strtok() must contain a NUL terminated string. the `read()` function will not append a NUL byte at the end of its' input. So the code must pay attention to the returned bytecount from `read()` and (assuming the byte count > 0) follow the call to `read()` with `buffer[bytecount] = '\0';` – user3629249 Jan 17 '16 at 00:03
  • regarding this line, after the call to `malloc()`: `buffer[len] = 0;` does not handle the problem. Perform the input string NUL byte appending after calling `read()` – user3629249 Jan 17 '16 at 00:06
  • regarding this line: `buffer = (char *)malloc((len+1)*sizeof(char));`, 1) `sizeof(char)` is defined as 1. Multiplying by 1 has absolutely no effect on the parameter passed to `malloc()` and just clutters the code. 2) in C, the returned value from `malloc()` has type `void*` which can be assigned to any pointer. Casting the returned value just clutters the code. Cluttering the code with useless (and error prone) expressions makes the code more difficult to understand, debug, maintain. Suggest removing those useless/misleading expressions – user3629249 Jan 17 '16 at 00:10
  • when printing an address using `printf()` use the `%p` format specifier, not %d. This line in the code causes the compiler to output a message. Strongly suggest, when compiling, to always enable all the warnings, then fix those warnings. (for gcc, at a minimum use: `-Wall -Wextra -pedantic` (I also use: `-Wconversion -std=c99` ) ) – user3629249 Jan 17 '16 at 00:13
  • in your first referenced example, the problem is that the string is a literal, in read only memory. (the call to strtok() is trying to change the readonly memory, which causes a 'access violation' resulting in a seg fault event. in the second referenced example, the phrase[] array only contains what ever trash was on the stack at that location. If that trash does not contain a space nor a NUL byte, then the call to `strtok()` will change something else, further down the stack. perhaps a return address, perhaps a pointer parameter. all undefined behaviour leading to a seg fault event. – user3629249 Jan 17 '16 at 16:30

1 Answers1

1

given the comments, and including error checking, the posted code needs to look similar to:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>



int main( void )
{

    char *buffer;
    int len;
    int sock;
    long addr = 0;
    //FILE *fptr;

    const char *s = "+";
    char *token;
    struct sockaddr_in address;
    ssize_t bytecount;

    if( 0 > (sock = socket( AF_INET, SOCK_STREAM, 0) ) )
    {
        perror( "socket failed");
        exit( EXIT_FAILURE );
    }


    // 'address' needs to be setup here
    // 'bind()' needs to be called here
    // 'connect()' needs to be called here

    addr = ((struct sockaddr_in *)&address)->sin_addr.s_addr;

    /* read length of message */
    bytecount = read(sock, &len, sizeof(int));
    if( sizeof(int) != bytecount )
    {
        fprintf( stderr, "read requested %d bytes but only got: %d bytes\n",
                (int)sizeof(int),
                (int)bytecount);
        exit( EXIT_FAILURE );
    }

    if (len > 0)
    {
        if( NULL == (buffer = malloc( (size_t)(len+1)) ) )
        { // then malloc failed
            perror( "malloc for buffer failed");
            exit( EXIT_FAILURE );
        }

        if( len == (bytecount = read( sock, buffer, (size_t)len ) ) )
        { // then correct number of bytes read
            buffer[bytecount] = '\0';
            printf("%s and %ld\n", buffer, addr);

            /* get the first token */
            token = strtok(buffer, s);
            printf( "token: %s\n", token);
        }
    }
}

otherwise we are only guessing as to the root of the problem.

Please update the posted code and let us know the result

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • thanks @user3629249 Still it is showing the Segmentation fault. – piyush-balwani Jan 17 '16 at 07:53
  • Running the exact code in the answer, on ubuntu linux 14.04 the only result is the output of the error message "read requested 4 bytes but only got: -1 bytes". (the -1 is the error indication returned from the call to `read()`) To help you further, we need two things from you. 1) the source code that is setting up 'address`, calling `bind()` calling `connect()` 2) the exact (probably displayed as 8 hex digits) the value read into the `len` variable. – user3629249 Jan 17 '16 at 16:18