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”
thenz1
是指向代码部分内存的指针,因此您无法更改它
如果您将其更改为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
achar*
(如果它是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编译器都会将字符串文本放在只读部分中,但并不要求它们这样做,过去默认情况下它们不会这样做。