Почему strsep () не работает с указателями на стек? - PullRequest
2 голосов
/ 06 апреля 2019

Похоже, что существует проблема совместимости указателя с использованием функции strsep для поиска первого слова строки. До сих пор я всегда думал, что char *s и char s[] полностью взаимозаменяемы. Но, похоже, это не так. Моя программа, использующая массив в стеке, выдает сообщение:

foo.c: In function ‘main’:
foo.c:9:21: warning: passing argument 1 of ‘strsep’ from incompatible pointer type [-Wincompatible-pointer-types]
  char *sub = strsep(&s2, " ");
                     ^
In file included from foo.c:2:0:
/usr/include/string.h:552:14: note: expected ‘char ** restrict’ but argument is of type ‘char (*)[200]’
 extern char *strsep (char **__restrict __stringp,

Я не понимаю проблемы. Программа с использованием malloc работает.

Это работает:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char s1[] = "Hello world\0";
    char *s2 = malloc(strlen(s1)+1);
    strcpy(s2, s1);
    char *sub = strsep(&s2, " ");

    printf("%s\n", sub);

    return 0;
}

Это не:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char s1[] = "Hello world\0";
    char s2[200];
    strcpy(s2, s1);
    char *sub = strsep(&s2, " ");

    printf("%s\n", sub);

    return 0;
}

В чем проблема? (Извините за strcpy). Почему важно, чтобы функции указателя указывали на стек или кучу? Я понимаю, почему вы не можете получить доступ к строкам в двоичном / текстовом сегменте, но в чем проблема со стеком?

1 Ответ

6 голосов
/ 06 апреля 2019
 note: expected ‘char ** restrict’ but argument is of type ‘char (*)[200]’

Ваше предупреждение точно указывает, в чем проблема.У вас есть два разных типа.

char *s2;        /* declares a character pointer */

, в то время как

char s2[200];   /* declares an array of char[200] */

Когда вы берете адрес указателя, результатом будет указатель на-указатель .Когда вы берете адрес массива, результатом будет указатель на массив .Когда вы разыменовываете указатель на указатель , результатом будет указатель .Когда вы разыменовываете указатель на массив , в результате получается массив .

strsep не был рассчитан на указатель на-array в качестве аргумента (что помешало бы перераспределению при необходимости)

...