0

这是 linux 内核用来去除字符串前导和尾随空格的代码:

char *strstrip(char *s)
{
        size_t size;
        char *end;

        size = strlen(s);

        if (!size)
                return s;

        end = s + size - 1;
        while (end >= s && isspace(*end))
                end--;
        *(end + 1) = '\0';

        while (*s && isspace(*s))
                s++;

        return s;
}

在这里,我这样使用它:

int main( void ){

    /* strip test*/
    char buffer2[60];
    char* testy2 = buffer2;
    testy2 = "       THING!      ";
    printf("The stripped string: \"%s\"\n",strstrip(testy2));
    return 0;
}

该程序编译正常,但执行时它指出:

Segmentation fault (core dumped)

为什么会这样?

4

4 回答 4

3

testy2( testy2 = " THING! ";) 的分配过程中,您将其指向静态只读存储器。

但是在您的strstrip()功能中,您正在尝试修改它。

testy2您可以通过使用malloc动态分配来解决它,例如:

testy2 = malloc( sizeof( "       THING!      " ) + 1 );
strcpy( testy2, s );

// But don't forget to free the memory at the end !
free( testy2 );
于 2013-08-14T18:33:15.467 回答
2
testy2 = "       THING!      ";

设置testy2为指向字符串文字。这可能存在于只读内存中,因此不能被strstrip.

您需要为testy2

const char* s = "       THING!      ";
testy2 = malloc(strlen(s)+1);
strcpy(testy2, s);
....
free(testy2);

buffer2或者,更简单,只需使用您要操作的字符串进行初始化

char buffer2[] = "       THING!      ";
printf("The stripped string: \"%s\"\n",strstrip(buffer2
于 2013-08-14T18:29:19.617 回答
2

代码中的字符串文字通常由编译器放置到程序内存空间的只读部分中。当您分配时testy2 = " THING! ";,您将设置testy2指向静态“只读”内存中的字符串文字。然后,当您调用strstrip()修改该内存时,您会得到一个 SIGSEGV,或者您的平台调用它的任何内容,此时strstrip()尝试写入 nul char ( '\0'),因为您无法写入属性设置为“只读”的内存”。要获取您可以修改的字符串文字的副本,您可以使用strcpy()它来制作它的副本,然后调用strstrip()该副本。当然要复制它,您必须将其复制到您拥有的内存中,您可以从中获取malloc(strlen(testy2)+1)new char[strlen(testy2)+1],或者正如您在原始帖子中所做的那样,通过创建本地分配。

需要注意的一点是,strstrip()1) 返回的指针可能与传入的指针不同,2) 可能会更改传递给它的内存中的字符串。在您的示例中,您丢失了返回的指针,因为您没有将它分配给任何东西......这并不是那么糟糕,因为您可以通过strstrip()再次调用原始指针来获取相同的指针地址,但是如果您多次需要剥离的字符串,效率会有点低。但是在这里要小心......如果您使用malloc()new为字符串文字的副本动态分配空间(并将返回的地址分配给指针,假设testy2),然后不要将 strstrip() 的返回值分配给该指针,否则您以后不能使用该指针来释放动态分配的内存!当您调用free()ordelete时,您需要将您从malloc()or中获得的原始指针传递给它new,而不是您从那里获得的指针strstrip()

于 2013-08-14T18:31:15.947 回答
2

线

testy2 = "       THING!      ";

没有做你认为它正在做的事情。它不是复制" THING! "buffer2. 它只是将指针设置为指向testy2字符串文字" THING! "。然后,当您调用该strstrip()函数时,该函数会尝试修改字符串文字,这是未定义的行为。因此,分段错误。

您可能想使用strcpy()而不是赋值运算符:

strcpy (testy2, "       THING!      ");
于 2013-08-14T18:34:26.740 回答