Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为函数中的指针赋值时出现分段错误_C_Pointers_Segmentation Fault_Undefined Behavior - Fatal编程技术网

C 为函数中的指针赋值时出现分段错误

C 为函数中的指针赋值时出现分段错误,c,pointers,segmentation-fault,undefined-behavior,C,Pointers,Segmentation Fault,Undefined Behavior,长时间侦听器,第一次调用 如果这个问题已经解决了,我真的很抱歉(我想它已经被广泛地涵盖了),但是我已经搜索了很多关于指针和其他似乎相关的主题的问题,但是我仍然无法解决我的问题 我目前正在为类项目编写字符串库,当我尝试此操作时遇到分段错误时: #include "str2107.h" #include <stdio.h> void lstrip(char *s) { char *p, *q; p = q = s; while (*p

长时间侦听器,第一次调用

如果这个问题已经解决了,我真的很抱歉(我想它已经被广泛地涵盖了),但是我已经搜索了很多关于指针和其他似乎相关的主题的问题,但是我仍然无法解决我的问题

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

#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';
}
#包括“str2107.h”
#包括
void lstrip(字符*s){
字符*p,*q;
p=q=s;
而(*p=''&&*p!='\0'){
*p++;
}
而(*p!='\0'){
*q=*p;//这是实际分段错误发生的地方。
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;
}
#包括
#包括
#包括“str2107.h”
int main(int argc,字符**argv){
char*z1=“weeee”;
printf(“lstrip函数\n”);
printf(“%s\n”,z1);
lstrip(z1);
printf(“%s\n”,z1);
返回0;
}

z1
指向字符串文字,修改字符串文字是错误的。或者,您可以使用以下可修改的
z1
声明:

char z1[] = "      weeee"; 
如果我们看看C99标准草案第6段(强调我的内容)中的字符串文字部分
6.4.5
String literals:

如果这些数组的元素具有 适当的值如果程序试图修改这样的数组,则该行为为 未定义。

WhozCraig还指出了以下几点:

while (*p == ' ' && *p != '\0') {
可以更简洁地写为:

while (*p == ' ' ) {
此外,您还在此处使用间接寻址:

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

p++;

当你写
char*z1=“weeee”
then
z1
是指向代码部分内存的指针,因此您无法更改它

如果您将其更改为char z1[]=“weeee”然后
z1
是堆栈上的字符数组,您可以更改它

如果您编写了
char const*z1=“…”那么这将是一个编译错误,这比分段错误更好

char *z1 = "      weeee";
应该是

const char *z1 = "      weeee";
因为字符串文字是常量。尝试以下方法:

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

在一个可变字符串上调用
lstrip
,同时保持
z2
a
char*
(如果它是
char[]
,这不是你想要的)。

正如许多其他人在你写作时已经指出的那样:

char*whatever=“some value”

这与:

char *whatever = malloc(length("some value") + 1); strcpy(whatever, "some value"); char*whatever=malloc(长度(“某些值”)+1); strcpy(无论什么,“某些值”); 区别在于文字(即编译时定义的字符串)可以是常量,尽管我不知道它是否总是常量或必须是常量。由于不应修改常量,并且您正在将“\0”字符放入字符串中,这将导致分段错误

char *z1 = "      weeee";
这可能有很多原因,但据我所知最简单的一个原因是,如果程序知道相同字符串的每次使用都可以安全地重用,那么它就可以进行优化

例如:

char *whatever1 = malloc(length("some value") + 1); strcpy(whatever1, "some value"); char *whatever2 = malloc(length("some value") + 1); strcpy(whatever2, "some value"); if(whatever1 == whatever2) { printf("This should never happen!\n"); } if("some value" == "some value") { printf("A good compiler should always do this!\n"); } char*whatever1=malloc(长度(“某些值”)+1); strcpy(whatever1,“某些值”); char*whatever2=malloc(长度(“某些值”)+1); strcpy(whatever2,“某些值”); 如果(whatever1==whatever2){ printf(“这永远不会发生!\n”); } 如果(“某个值”==“某个值”){ printf(“一个好的编译器应该总是这样做!\n”);
}无关:我希望您在while条件下看到这个表达式的后半部分是徒劳的:
(*p=''&&*p!='\0')
。在什么可能的情况下,第一部分为真,第二部分为假???较短的版本:
(*p='')
谢谢您指出这一点+谢谢你的解释。他说的也是,谢谢你的解释。它确实澄清了一些事情!请注意,在尝试修改字符串文字时调用未定义的行为,字符串文字在C.@ElchononEdelson True中没有
const
类型。也许我不清楚是否应该进行更改以防止意外导致未定义的行为,而不是类型协议。另一种解决方案是编写
charz1[]=“weeee”,将
z1
创建为数组而不是指针。字符串文字在C中不是常量。也就是说,它们没有
const
类型。标准所说的只是,如果您的程序试图修改一个,那么行为是未定义的。大多数当前的C编译器都会将字符串文本放在只读部分中,但并不要求它们这样做,过去默认情况下它们不会这样做。