简体   繁体   中英

Return char[] to used it in strtok() function

I have function

char *priq_pop(pri_queue q, int *pri)
{
    char *out;
    if (q->n == 1) return 0;

    q_elem_t *b = q->buf;

    out = b[1].data;
    if (pri) *pri = b[1].pri;

    /* pull last item to top, then down heap. */
    --q->n;

    int n = 1, m;
    while ((m = n * 2) < q->n) 
    {
        if (m + 1 < q->n && b[m].pri > b[m + 1].pri)
        {
            m++;
        }

        if (b[q->n].pri <= b[m].pri)
        {
            break;
        }
        b[n] = b[m];
        n = m;
    }

    b[n] = b[q->n];
    if (q->n < q->alloc / 2 && q->n >= 16)
    q->buf = realloc(q->buf, (q->alloc /= 2) * sizeof(b[0]));

    return (char *)out;
}

And I need to use returned value in main() :

int main()
{
    pri_queue qq = priq_new(0);
    char test[] = "test1,test2";
    char *ret;
    int pp;
    char *x;
    char *y;

    priq_push(qq, "test2", 2);
    priq_push(qq, "test,s", 0);

    ret = priq_pop(qq, &pp);
    printf("%s\n\n", ret);

    x = strtok(ret, ",");
    y = strtok(NULL, ",");

    printf("%s\n%s", x, y); 

    return 0;
}

But with this code, my program stop working, when it gets to x = strtok(ret, ","); . Error is in returned value (in ret ), because if I use variable test , it's work. How can I fix my problem please?

You are pushing constant string literals onto your queue here:

priq_push(qq, "test2", 2);
priq_push(qq, "test,s", 0);

"test2" and "test,s" are string literals, and you're pushing pointers to them onto your priority queue. String literals are not writeable.

When you pop from your priority queue, you're getting back the same pointer you pushed, and then handing it to strtok . strtok needs to modify the string it is passed. But, because you're passing it a pointer to a string literal, it results in an exception.

You need to pass writeable strings to strtok . That requires either making a copy before you push it onto the queue (and freeing it when you're done with it), or making a copy when you pop it off the queue (and, again, freeing it when you're done with it).

You can either use strlen , malloc and strcpy to make the writeable copies, or the commonly available (but nonstandard) strdup .

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