首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么strsep()不能使用指向堆栈的指针?

为什么strsep()不能使用指向堆栈的指针?
EN

Stack Overflow用户
提问于 2019-04-06 05:40:33
回答 2查看 455关注 0票数 3

使用函数strsep查找字符串的第一个单词似乎存在指针兼容性问题。到目前为止,我一直认为char *schar s[]是完全可以互换的。但看起来并非如此。我在堆栈上使用数组的程序失败,并显示以下消息:

代码语言:javascript
复制
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的程序可以工作。

这是可行的:

代码语言:javascript
复制
#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;
}

这不是:

代码语言:javascript
复制
#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感到抱歉)。为什么指针指向堆栈还是堆对函数很重要?我理解为什么你不能访问二进制/文本段中的字符串,但是堆栈有什么问题呢?

EN

回答 2

Stack Overflow用户

发布于 2019-04-06 05:52:57

代码语言:javascript
复制
 note: expected ‘char ** restrict’ but argument is of type ‘char (*)[200]’

您的警告会准确地告诉您问题所在。你有两种不同的类型。

代码语言:javascript
复制
char *s2;        /* declares a character pointer */

代码语言:javascript
复制
char s2[200];   /* declares an array of char[200] */

当您将的地址作为指针时,结果是指针到指针。当您获取 an数组的地址时,结果是指向数组的指针。当您取消引用指针到指针时,结果是一个指针。当您取消引用指向数组的指针时,结果是一个数组。

strsep没有被设计为接受指向数组的指针作为参数(这将阻止它根据需要重新分配)

票数 7
EN

Stack Overflow用户

发布于 2021-05-08 20:28:15

@DavidRankin关于为什么它不起作用是正确的。但您仍然可以编写代码,以便它可以在堆栈上使用变量。

要使用数组代替malloc(),可以创建另一个指向数组的指针,并将其用作strsep()的参数,如version1()函数所示。

我知道这可能只是一个示例,但是您提供的malloc()和strsep()示例可能会导致内存错误,因为strsep()会更新指针(它会修改它所指向的地址)。因此,您必须保存malloc()返回的原始地址,以便正确地释放该内存。请参见version2()示例。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void version1(void)
{
    char s1[] = "Hello world";
    char s2[200];
    char* s3 = s2;
    char *sub;

    strcpy(s3, s1); // or s2 in place of s3

    while ((sub = strsep(&s3, " ")))
    {
        printf("%s\n", sub);
    }
}

void version2(void)
{
    char s1[] = "Hello world";
    char *mymem = malloc(strlen(s1)+1);
    char *s2 = mymem;
    char *sub;

    strcpy(s2, s1);

    while ((sub = strsep(&s2, " ")))
    {
        printf("%s\n", sub);
    }

    free(mymem);
}

int main(int argc, char* argv[])
{
    printf("Version1\n");
    version1();

    printf("\nVersion2\n");
    version2();

    return 0;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55543717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档