6

长期聆听者,第一次来电者。

如果这个问题已经得到解决,我深表歉意(我想这已经被广泛讨论),但我已经搜索了许多关于指针和其他看似相关主题的问题,但我仍然无法解决我的问题。

我目前正在为类项目编写一个字符串库,当我尝试这个时遇到分段错误错误:

#include "str2107.h"
#include <stdio.h>

void lstrip(char *s) {

        char *p, *q;
        p = q = s;

        while (*p == ' ' && *p != '\0') {
             *p++;
        }

        while (*p != '\0') {
            *q = *p;   //this is where the actual segmentation fault occurs.
            p++;
            q++;
        }

        *q = '\0';
}

我的主程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include "str2107.h"


int main(int argc, char** argv) {

    char *z1 = "      weeee";
    printf("lstrip function\n");
    printf("%s\n",z1);
    lstrip(z1);
    printf("%s\n",z1);

    return 0;
}
4

4 回答 4

6

z1指向字符串文字,修改字符串文字是未定义的行为。或者,您可以使用以下z1可修改的声明:

char z1[] = "      weeee"; 

如果我们看一下 C99 草案标准部分6.4.5 字符串文字6段说(强调我的):

如果它们的元素具有适当的值,则未指定这些数组是否不同。如果程序尝试修改这样的数组,则行为未定义。

WhozCraig 指出的其他几点:

while (*p == ' ' && *p != '\0') {

可以更简洁地写成:

while (*p == ' ' ) {

你也在这里使用间接

*p++;

但您实际上并没有使用结果值,因此您可以将其更改为:

p++;
于 2013-10-29T15:55:02.367 回答
1

When you write char *z1 = " weeee"; then z1 is a pointer that points to a memory that is in the code part, so you can't change it.

If you change it char z1[] = " weeee"; then z1 is an array of chars that are on the stack and you can change it.

If you had wrote char const *z1 = "..."; then it would be a compilation error, which is better and preferable over segmentation fault.

于 2013-10-29T15:56:05.453 回答
0
char *z1 = "      weeee";

应该

const char *z1 = "      weeee";

因为字符串文字是常量。尝试类似:

const char *z1 = "      weeee";
char *z2 = strdup(z1);
lstrip(z2);

lstrip在保持z2a 的同时调用可变字符串char*(如果它char[]不是你想要的)。

于 2013-10-29T15:57:59.860 回答
0

正如许多其他人已经向您指出的那样,当您编写时:

char *whatever = "some value";

这与:

char *whatever = malloc(length("some value") + 1);
strcpy(无论如何,“一些价值”);

不同之处在于文字(即在编译时定义的字符串)可以是常量,尽管我不知道它是否总是必须是常量。由于不应修改常量,并且您将 '\0' 字符放入字符串中,这会导致分段错误。

这可能有很多原因,但我知道的一个简单的原因是,如果程序知道每次使用相同的字符串都可以安全地重用,它就可以进行优化。

举个例子:

char *whatever1 = malloc(length("some value") + 1);
strcpy(whatever1, "某个值");
char *whatever2 = malloc(length("some value") + 1);
strcpy(whatever2, "某个值");
如果(随便 1 == 随便 2){
  printf("这绝不应该发生!\n");
}

if("某个值" == "某个值") {
  printf("一个好的编译器应该总是这样做!\n");
}
于 2013-10-29T16:12:38.690 回答