簡體   English   中英

為什么 strsep() 不能使用指向堆棧的指針?

[英]Why doesn't strsep() work with pointers to the stack?

使用函數strsep查找字符串的第一個單詞似乎存在指針兼容性問題。 到目前為止,我一直認為char *schar 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 )。 為什么指針指向堆棧或堆對函數很重要? 我明白為什么你不能訪問二進制/文本段中的字符串,但是堆棧有什么問題?

 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並非旨在將指向數組指針作為參數(這會阻止它根據需要重新分配)

@DavidRankin 關於為什么它不起作用是正確的。 但是您仍然可以編寫代碼,以便它可以使用堆棧上的變量。

要使用數組代替 malloc(),您可以創建另一個指向該數組的指針,並將其用作 strsep() 的參數,如 version1() 函數中所示。

我知道這可能只是一個示例,但是您提供的 malloc() 和 strsep() 示例可能會導致內存錯誤,因為 strsep() 將更新指針(它會修改它指向的地址)。 因此,您必須保存 malloc() 返回的原始地址,以便正確釋放該內存。 請參閱 version2() 示例。

#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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM