1

我正在尝试编写一个就地反向函数并且几乎完全遵循在线代码,但运行以下程序会引发总线错误。我是否将错误类型的参数传递给 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;
}
4

4 回答 4

16

要知道发生了什么,您必须了解 C 程序的内存布局。

char *s = "sample";    // Here the "sample" string is placed in 
                        // the read only memory of the Initialized Data segment. 

在这里,您不能修改数据。" s" 是指向char const("sample") 的指针,您正在尝试修改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            |
|                                   |
|-----------------------------------|
于 2013-08-28T05:24:14.303 回答
4

你可能想改变

char *s = "sample";  //Pointer to string literal

char s[] = "sample";  // mutable copy of string literal

尝试和修改字符串文字是未定义的行为,它们应该用作const char *.


可能无关,但一个建议,

当你做类似的事情时*end--,你可能想要放括号,以便它做你认为它做的事情。

以上可以

(*end)--

或者

 *(end--)

而且您需要很好地掌握优先规则,以确保您想要的是正在发生的事情。

于 2013-08-28T04:03:18.503 回答
3

您的反向功能是完全正确的。您的主要功能部分只有几件事:

  • char[]正如 KarthikT 所说, s不应该是char*因为更改文字是未定义的。

  • 在您的 printf 函数中,您忘记将 s 作为参数。

  • return 0是成功的。return 1是错误。

所以新的主要应该是这样的:

int main() {
    char s[] = "sample";
    reverse(s);
    printf("%s\n", s);
    return 0;
}

输出:

elpmas
于 2013-08-28T04:15:35.517 回答
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
于 2013-08-28T07:01:15.047 回答