简体   繁体   中英

Segmentation fault? String tokenization

I'm trying to write a function will convert the characters from an array into ints so that I can produce a sum or other math process for each group. I know that first I have to use strtok to get rid of the spaces and '+'. I've been trying to first at least start with getting strtok to work but it keeps saying segmentation fault when I try to run it.

Any help?

#include <string.h>
#include <stdio.h>
int main(void)
{
    char* string[] = { "10 + 20", "1 + 3 + 6 + 8" };
    sum(string[0]);
}

int sum(char* s)
{
    char *stringcopy = malloc( strlen(s) + 1 );     
    char* del = " +";                                  
    char* token;
    int i;

    stringcopy = s;   /* 'copy' problem here */             

    token = strtok(stringcopy, del);
    while( token ) {
       printf("%s\n", token);
       token = strtok(NULL, del);
    }
    return 11;   /* placeholder until I get the sum */
}

There is a simple reason strtok gives you a segmentation fault:

You are running it on a string literal, which despite having type char[n] is an immutable object.
strtok modifies any string you run it on!

The work-around is simple: Run on a copy. Here a function for duplicating strings (most C libraries provide this non-standard function as char* strdup(const char*) :

char* my_strdup(const char* s) {
    size_t size = strlen(s)+1;
    char* ret = malloc(size);
    if(ret)
        memcpy(ret, s, size);
    return ret;
}

Don't forget to free() the copy later.

You tried doing so, but after getting off to a good start and reserving space for the string with malloc , you just discarded it (memory leak) by assigning a pointer to the literal to that same pointer.

This line does not do what you thought it would:

textcopy = s;   /* making copy for strtok */             

No string is copied here. All that happens is that instead of pointing to the first byte of the block of memory that you just allocated for it (with malloc( strlen(s) + 1 ) ), textcopy now points directly at the first byte of the literal string "10 + 20" that you passed to stringSum as s .

You probably wanted something like strcpy(textcopy, s) . I had suggested strncpy earlier; strncpy(textcopy, s, strlen(s)) + 1 might work, but (as the comments explain) seems to be rather pointless to use in this context.

This statement

textcopy = s;   /* making copy for strtok */

does not do what you think.

In fact there us a memory leak because at first you allocated memory and textcopy got the address of the first byte of the storage

char *textcopy = malloc( strlen(s) + 1 );

and then you reassigned textcopy.

textcopy = s;   /* making copy for strtok */

You have to use standard function strcpy instead

strcpy( textcopy, s );   /* making copy for strtok */

Also it would be better if the function would declared as

int stringSum(const char* s);

The line

textcopy = s;   /* making copy for strtok */             

doesn't make copy of s and put it in textcopy . Instead, you need to use:

strcpy(textcopy, s);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM