我正在尝试编写就地反向函数并且几乎完全遵循在线代码,但运行以下程序会引发总线错误。我是否将错误的参数传递给reverse()?
void reverse(char *str) {
char * end = str;
char tmp;
if (str) {
while (*end) {
++end;
}
--end;
while (str < end) {
tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
}
int main() {
char *s = "sample";
reverse(s);
printf("%s\n");
return 1;
}
答案 0 :(得分:16)
要知道发生了什么,你必须要了解C程序的内存布局。
char *s = "sample"; // Here the "sample" string is placed in
// the read only memory of the Initialized Data segment.
在这里,您无法修改数据。 “s
”是指向char const
(“示例”)的指针,您正在尝试修改char const
。这就是您收到bus error
错误的原因。
|Stack frame of main() |
|char *s |
|-------------------------------|
|Stack frame of reverse() |
|char *end |
|char tmp |
| |
|-------------------------------|
| |
| |
| |
| |
| |
|-------------------------------|
| |
| HEAP |
| |
|-------------------------------|
| |
| UNINITIALIZED DATA (BSS) |
| |
|-------------------------------|
| |
| INITIALIZED DATA |
| |
|"sample" | |
| | |
|(Read Only)| (Read/Write) |
|-------------------------------|
| Text or Code Segment |
| |
|-------------------------------|
的更新强> 的 帖子下方与您的问题无关。但是如果你知道在C中为所有变量分配的内存在哪里,那么你可以更好地编码。 以下程序可以更好地理解C程序的内存布局。 我没有在图中包含命令行参数,函数参数和函数的返回值。 想要更新这篇文章的人可以在图中添加命令行参数,函数参数和函数返回值。
|Stack frame of main() |
|local_To_Main |
| | #include <stdio.h>
|-----------------------------------| #include <stdlib.h>
|Stack frame of function1() | int gVariable1 = 100;
|local_To_Function1 | int gVariable2;
|iptr | char cstring[10] = "Hello";
| \ STACK | char* cptr = "Hello World";
|------\---------------|------------| void function1(void)
| \ \|/ | {
| \ | static int j = 5;
| \ | int local_To_Function1;
| \ ^ | int *iptr;
| \ | | iptr = (int *) malloc(sizeof(int));
|------------\---------------|------| free(iptr);
| HEAP \ --- | }
| \---> |int| |
| --- | int main(void)
|-----------------------------------| {
| | static int i;
| UNINITIALIZED DATA (BSS) | int local_To_Main;
|gVariable2(initialized to 0) |
|i (initialized to 0) |
|-----------------------------------| function1();
| | return 0;
| INITIALIZED DATA | }
| |
|"Hello World" |gVariable1 =100 |
| ^ |cstring="Hello" |
| | |j=5 |
| |---<---<---- cptr |
|(Read Only) | (Read/Write) |
|-----------------------------------|
| Text or Code Segment |
| |
|-----------------------------------|
答案 1 :(得分:4)
您可能想要更改
char *s = "sample"; //Pointer to string literal
到
char s[] = "sample"; // mutable copy of string literal
尝试修改字符串文字是未定义的行为,它们应该用作const char *
。
可能不相关,但有建议,
当您执行*end--
之类的操作时,您可能需要放置paranthesis,以便它能够执行您认为的操作。
以上可以
(*end)--
或
*(end--)
你需要很好地掌握优先规则,以确定你想要的是正在发生的事情。
答案 2 :(得分:3)
您的反向功能完全正确。主要功能部分只是一些事情:
正如KarthikT所说,s应该是char[]
而不是char*
,因为更改字面值是未定义的。
,你忘了把s作为参数。
return 0
成功。 return 1
是错误的。
所以新的主要应该是:
int main() {
char s[] = "sample";
reverse(s);
printf("%s\n", s);
return 0;
}
输出:
elpmas
答案 3 :(得分:1)
char *str="sample";
此处示例存储在只读存储器中,因此您永远不能对此类文字进行修改。
为了进行操作,您必须将文字存储在读写内存中。 以下代码可以解决您的问题。
#include<stdio.h>
void reverse(char *str)
{
char temp,*end;
for(end=str;*end;end++);
end--;
for(;str<end;temp=*str,*(str++)=*end,*(end--)=temp);
}
int main()
{
char str[]="sample"; //stored in read-write memory
reverse(str);
printf("%s\n",str);
return 0;
}
输出:
elpmas